Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การจัดการตารางที่แบ่งพาร์ติชัน PostgreSQL ด้วย Ruby

เราใช้ตารางที่แบ่งพาร์ติชันในฐานข้อมูล PostgreSQL หลักของเราเพื่อทำให้ข้อมูลเก่าหมดอายุอย่างมีประสิทธิภาพ เนื่องจากการลบข้อมูลจำนวนมากออกจากตารางขนาดใหญ่อาจทำให้ประสิทธิภาพของฐานข้อมูลลดลง ก่อนหน้าเวอร์ชัน 10 PostgreSQL ไม่มีการสนับสนุนดั้งเดิมสำหรับตารางที่แบ่งพาร์ติชัน ดังนั้นเราจึงใช้ส่วนขยาย pg_partman เพื่อใช้การแบ่งพาร์ติชัน มันทำงานโดยใช้การสืบทอดตารางของ PostgreSQL เพื่อสร้างตารางย่อยของตารางที่จะแบ่งพาร์ติชั่นและทริกเกอร์ให้แทรกข้อมูลลงในตารางย่อยแทนที่จะเป็นตารางหลัก ส่วนขยายนั้นทำงานได้ดีสำหรับเรา แต่มีข้อเสีย - ไม่ใช่ตัวเลือกเมื่อคุณใช้ Amazon RDS เนื่องจากไม่รองรับ เมื่อ PostgreSQL รองรับเนทิฟพาร์ติชั่นแล้ว ฉันคิดว่าถึงเวลาที่จะต้องทิ้งส่วนขยายนั้นแล้ว เราจึงมีตัวเลือกในการใช้ RDS

กรณีการใช้งานการแบ่งพาร์ติชันของเราค่อนข้างง่าย:เราแบ่งตารางตามเวลา สร้างพาร์ติชันใหม่สำหรับทุกวัน สัปดาห์ หรือเดือน ขึ้นอยู่กับจำนวนแถวที่เราต้องการเก็บไว้ในพาร์ติชันทั้งหมด และระยะเวลาที่เราต้องการเก็บ ข้อมูล. ตารางที่แบ่งพาร์ติชันทั้งหมดของเรามี created_at คอลัมน์ที่จะใช้กำหนดพาร์ติชั่นที่เก็บแต่ละแถว ตัวอย่างเช่น เราอาจมีตารางที่กำหนดไว้ดังนี้:

create table events (
  project_id integer,
  data jsonb,
  created_at timestamp
)
partition by range (created_at);

และถ้าเราต้องการมีพาร์ติชั่นรายสัปดาห์ ก็จะมีลักษณะดังนี้:

create table events_p2019_10_28 partition of events for values from ('2019-10-28') to ('2019-11-04');
create table events_p2019_11_04 partition of events for values from ('2019-11-04') to ('2019-11-11');

ด้วยรูปแบบการแบ่งพาร์ติชั่นตามเวลา การลบข้อมูลเก่าทำได้ง่ายเพียงแค่ทิ้งพาร์ติชั่นตัวใดตัวหนึ่ง การบำรุงรักษาตามปกติที่เราต้องทำคือสร้างพาร์ติชั่นใหม่สำหรับช่วงวันที่เมื่อเราเข้าใกล้มันและลบพาร์ติชั่นเก่าที่มีข้อมูลที่เราไม่ต้องการอีกต่อไป เพื่อให้การบำรุงรักษาง่ายขึ้นเล็กน้อย ฉันได้สร้าง pg_partition_manager gem โดยธรรมชาติแล้ว มันได้รับแรงบันดาลใจจากประสบการณ์ของฉันเกี่ยวกับส่วนขยาย pg_partman ซึ่งให้บริการเราเป็นอย่างดี

มาดูกันว่าคุณจะใช้อัญมณีนี้อย่างไร โดยพิจารณาจากตารางเหตุการณ์และรูปแบบการแบ่งพาร์ติชั่นที่อธิบายข้างต้น คุณจะสร้างงานสคริปต์หรือเรคที่มีลักษณะดังนี้:

require "pg_partition_manager"

PgPartitionManager::Time.process([{parent_table: "public.events", period: "week", premake: 1, retain: 3}])

parent_table ถูกกำหนดเป็น schema.table_name (public สคีมาเริ่มต้นมักเป็นเพียงคนเดียวที่นักพัฒนา Rails ลงเอยด้วย) period อาจเป็นวัน สัปดาห์ หรือเดือน คุณสามารถเลือกจำนวนตารางที่คุณต้องการสร้างล่วงหน้า (หลังจากช่วงเวลาปัจจุบัน) ด้วย premake และจำนวนตารางที่คุณต้องการเก็บไว้ (ก่อนช่วงเวลาปัจจุบัน) ด้วย retain . อัญมณีมีค่าเริ่มต้นในการสร้าง 4 ตารางล่วงหน้าหากคุณไม่ระบุ premake และค่าเริ่มต้นจะเก็บข้อมูลไว้ 7 วัน 4 สัปดาห์ และ 6 เดือน ถ้าคุณไม่ระบุ retain .

เรียกใช้สคริปต์/งานนั้นด้วยงาน cron รายวัน และคุณพร้อมแล้ว - มันจะสร้างและวางตารางตามต้องการ

แบบสอบถาม ActiveRecord ทั้งหมดทำงานเหมือนกับที่ทำกับตารางที่ไม่มีการแบ่งพาร์ติชัน คุณจึงไม่จำเป็นต้องเปลี่ยนแปลงโค้ดของคุณ นั่นคือ Event.create , Event.where ฯลฯ จะทำงานเหมือนเช่นเคย โดย PostgreSQL จะใส่ข้อมูลในพาร์ติชั่นที่เหมาะสมสำหรับคุณเมื่อคุณแทรก มีการเปลี่ยนแปลงอย่างหนึ่งที่คุณอาจสังเกตเห็นได้หากคุณมีข้อมูลจำนวนมาก แม้ว่า... เมื่อคุณใส่ created_at ในการสืบค้นของคุณ PostgreSQL จะไม่ต้องสแกนพาร์ติชั่นทั้งหมด -- แค่พาร์ติชั่นที่ครอบคลุมช่วงที่คุณระบุในส่วนคำสั่ง where ของคุณ

โดยสรุป หากคุณมีข้อมูลตามเวลาจำนวนมากที่คุณต้องการลบเมื่อข้อมูลหมดอายุ ให้ใช้ตารางที่แบ่งพาร์ติชัน PostgreSQL และ pg_partition_manager gem เพื่อทำให้แอปของคุณมีความสุข :)