قفل کردن سطح ستون YugabyteDB برای UPDATE
در یک پست وبلاگ قبلی که نحوه تغییر نوع داده یک ستون را بدون توقف برنامه نشان می داد، مرحله ای وجود دارد که باید ستون جدید را از ستون قدیمی به روز کنیم. در همان زمان، برنامه ممکن است مقداری DML را اجرا کند. به همین دلیل است که به روز رسانی باید در تراکنش های کوچک انجام شود.
من اشاره کردم که DMLهایی که ممکن است مسدود شوند DELETE و UPDATE ستونی است که دوباره تایپ شده است.
دلیل تداخل DELETE با بهروزرسانیهای همزمان واضح است: کل ردیف قفل است.
دلیل عدم تداخل INSERT، حتی اگر ستون جدید توسط ماشه بهروزرسانی شود، به دلیل سطح جداسازی READ COMMITTED است که میتواند ردیفهای جدید را نادیده بگیرد.
دلیل اینکه من فقط به روز رسانی ستون تایپ مجدد را ذکر کردم این است در YugabyteDB فقط ستون های به روز شده قفل می شوند. در PostgreSQL، هر به روز رسانی، حتی در ستون های دیگر، در تضاد بود.
در اینجا چیزی است که می توانید برای بازتولید اجرا کنید، از پست وبلاگ در تایپ مجدد یک ستون گرفته شده است:
drop table if exists demo;
create table demo ( k bigserial primary key, a int, v int default 0);
insert into demo(a) select generate_series(1,100);
alter table demo add column a_new bigint;
create or replace function a_new() returns trigger as $$
begin new.a_new := new.a; return new; end; $$ language plpgsql;
create trigger a_new_trigger
before insert or update of a on demo for each row
execute function a_new();
begin transaction;
insert into demo values(0,42);
update demo set v=v+1 where k=2;
\! psql -ec 'set statement_timeout to 3000' -c 'update demo set a_new=a where a_new is null'
commit;
من استفاده می کنم \! psql -ec
برای اجرای UPDATE همزمان از یک جلسه دیگر.
در PostgreSQL، این به روز رسانی با شکست مواجه می شود ERROR: canceling statement due to statement timeout CONTEXT: while locking tuple (0,2) in relation "demo"
زیرا به روز رسانی ستون v
ردیف را قفل کرده است:
اجرای مشابه در YugabyteDB مسدود نمی شود و شکست نمی خورد:
دلیل آن این است که به روز رسانی ستون v
فقط این ستون را در ردیف قفل کرده است. و سپس با به روز رسانی ستون در تضاد نیست a_new
(از طریق ماشه).
سطح قفل با فناوری پایگاه داده بهبود می یابد. قدیمیترین پایگاههای داده در حال افزایش قفلها به سطح جدول بودند. برخی هنوز میتوانند روی یک بلوک کامل مانند اوراکل منتظر بمانند، در حالی که فضای خالی کافی برای اطلاعات قفل ندارند. PostgreSQL در سطح ردیف قفل می شود. YugabyteDB، به لطف ذخیره سازی کلید-مقدار با مقادیر ردیف و ستون به عنوان اسناد، اطلاعات قفل را در پایین ترین سطح ذخیره می کند.