باز کردن قفل Postgres Lock Manager. بروس مومجیان

متن سخنرانی بروس مومجیان در سال 2020 "باز کردن قفل مدیر قفل Postgres".

باز کردن قفل Postgres Lock Manager. بروس مومجیان

(توجه: تمام پرس و جوهای SQL از اسلایدها را می توانید از این لینک دریافت کنید: http://momjian.us/main/writings/pgsql/locking.sql)

سلام! خیلی خوب است که دوباره اینجا در روسیه هستم. ببخشید پارسال نتونستم بیام ولی امسال من و ایوان برنامه های بزرگی داریم. امیدوارم بیشتر اوقات اینجا باشم. من عاشق آمدن به روسیه هستم. من از Tyumen، Tver بازدید خواهم کرد. بسیار خوشحالم که می توانم از این شهرها دیدن کنم.

نام من بروس مومجیان است. من در EnterpriseDB کار می کنم و بیش از 23 سال است که با Postgres کار می کنم. من در فیلادلفیا، ایالات متحده آمریکا زندگی می کنم. من حدود 90 روز در سال سفر می کنم. و در حدود 40 کنفرانس شرکت می کنم. من سایت اینترنتی، که شامل اسلایدهایی است که اکنون به شما نشان خواهم داد. بنابراین، پس از کنفرانس می توانید آنها را از وب سایت شخصی من دانلود کنید. همچنین شامل حدود 30 ارائه است. همچنین ویدیوها و تعداد زیادی ورودی وبلاگ، بیش از 500 مورد وجود دارد. این یک منبع نسبتاً آموزنده است. و اگر به این مطالب علاقه دارید، از شما دعوت می کنم از آن استفاده کنید.

من قبل از شروع کار با Postgres معلم بودم، استاد بودم. و من بسیار خوشحالم که اکنون می توانم آنچه را که می خواهم به شما بگویم، به شما بگویم. این یکی از جالب ترین ارائه های من است. و این ارائه شامل 110 اسلاید است. ما با چیزهای ساده شروع به صحبت می کنیم و در پایان گزارش پیچیده تر و پیچیده تر می شود و کاملاً پیچیده می شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این یک مکالمه نسبتاً ناخوشایند است. مسدود کردن محبوب ترین موضوع نیست. ما می خواهیم این یک جایی ناپدید شود. مثل رفتن به دندانپزشکی است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

  1. قفل کردن برای بسیاری از افرادی که در پایگاه‌های داده کار می‌کنند و چندین فرآیند همزمان در حال اجرا هستند، مشکل است. آنها نیاز به مسدود کردن دارند. یعنی امروز به شما دانش اولیه در مورد مسدود کردن می دهم.
  2. شناسه های تراکنش این بخش نسبتاً خسته کننده از ارائه است، اما آنها باید درک شوند.
  3. در ادامه در مورد انواع مسدود کردن صحبت خواهیم کرد. این یک بخش نسبتاً مکانیکی است.
  4. و در زیر چند نمونه از مسدود کردن را بیان خواهیم کرد. و درک آن بسیار دشوار خواهد بود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بیایید در مورد مسدود کردن صحبت کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اصطلاحات ما بسیار پیچیده است. چند نفر از شما می دانید که این قسمت از کجا آمده است؟ دو نفر. این از یک بازی به نام ماجراجویی غار عظیم است. فکر می کنم این یک بازی کامپیوتری مبتنی بر متن در دهه 80 بود. در آنجا باید به یک غار می رفتی، به یک هزارتو، و متن تغییر می کرد، اما محتوا تقریباً هر بار یکسان بود. اینطوری یاد این بازی افتادم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و در اینجا نام قفل هایی را می بینیم که از Oracle به ما رسیده است. ما از آنها استفاده می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در اینجا اصطلاحاتی را می بینیم که من را گیج می کند. برای مثال، SHARE UPDATE ECXLUSIVE. بعدی RAW EXLUSIVE را به اشتراک بگذارید. صادقانه بگویم، این اسامی چندان واضح نیستند. ما سعی خواهیم کرد آنها را با جزئیات بیشتری در نظر بگیریم. برخی از آنها حاوی کلمه اشتراک هستند که به معنای جدا کردن است. برخی حاوی کلمه "انحصاری" هستند. برخی شامل هر دو این کلمات هستند. من می خواهم با نحوه کار این قفل ها شروع کنم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و کلمه "دسترسی" نیز بسیار مهم است. و کلمات "ردیف" یک رشته هستند. یعنی توزیع دسترسی، توزیع ردیف.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

موضوع دیگری که باید در Postgres فهمیده شود و متأسفانه نمی توانم در سخنرانی خود به آن بپردازم MVCC است. من یک ارائه جداگانه در مورد این موضوع در وب سایت خود دارم. و اگر فکر می کنید این ارائه سخت است، MVCC احتمالا سخت ترین است. و در صورت علاقه می توانید آن را در وب سایت تماشا کنید. می توانید ویدیو را تماشا کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

چیز دیگری که باید بدانیم شناسه تراکنش ها است. بسیاری از تراکنش ها بدون شناسه های منحصر به فرد نمی توانند کار کنند. و در اینجا توضیحی داریم که تراکنش چیست. Postgres دارای دو سیستم شماره گذاری تراکنش است. می دانم که این راه حل چندان زیبایی نیست.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

همچنین به خاطر داشته باشید که درک اسلایدها بسیار دشوار خواهد بود، بنابراین آنچه با رنگ قرمز مشخص شده است همان چیزی است که باید به آن توجه کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

http://momjian.us/main/writings/pgsql/locking.sql

اجازه بدید ببینم. شماره تراکنش با رنگ قرمز مشخص شده است. تابع SELECT pg_back در اینجا نشان داده شده است. تراکنش من و شناسه تراکنش را برمی گرداند.

یک چیز دیگر، اگر این ارائه را دوست دارید و می خواهید آن را در پایگاه داده خود اجرا کنید، می توانید به این لینک به رنگ صورتی بروید و SQL را برای این ارائه دانلود کنید. و شما به سادگی می توانید آن را در PSQL خود اجرا کنید و کل ارائه بلافاصله روی صفحه نمایش شما خواهد بود. این شامل گل نخواهد بود، اما حداقل ما می توانیم آن را ببینیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در این حالت شناسه تراکنش را می بینیم. این شماره ای است که به او اختصاص داده ایم. و نوع دیگری از شناسه تراکنش در Postgres وجود دارد که به آن شناسه تراکنش مجازی می گویند

و ما باید این را درک کنیم. این بسیار مهم است، در غیر این صورت ما قادر به درک قفل در Postgres نخواهیم بود.

شناسه تراکنش مجازی یک شناسه تراکنش است که حاوی مقادیر ثابت نیست. به عنوان مثال، اگر من یک دستور SELECT را اجرا کنم، به احتمال زیاد پایگاه داده را تغییر نمی دهم، هیچ چیزی را قفل نمی کنم. بنابراین وقتی یک SELECT ساده را اجرا می کنیم، به آن تراکنش شناسه دائمی نمی دهیم. آنجا فقط یک شناسه مجازی به او می دهیم.

و این عملکرد Postgres را بهبود می بخشد، قابلیت پاکسازی را بهبود می بخشد، بنابراین شناسه تراکنش مجازی از دو عدد تشکیل شده است. اولین عدد قبل از اسلش ID Backend است. و در سمت راست فقط یک شمارنده می بینیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین، اگر درخواستی را اجرا کنم، می گوید که شناسه پشتیبان 2 است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر من یک سری از این تراکنش ها را اجرا کنم، می بینیم که هر بار که یک کوئری اجرا می کنم، شمارنده افزایش می یابد. به عنوان مثال، زمانی که من کوئری 2/10، 2/11، 2/12 و غیره را اجرا می کنم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

به خاطر داشته باشید که در اینجا دو ستون وجود دارد. در سمت چپ، شناسه تراکنش مجازی - 2/12 را می بینیم. و در سمت راست یک شناسه تراکنش دائمی داریم. و این فیلد خالی است. و این تراکنش پایگاه داده را تغییر نمی دهد. بنابراین من به آن شناسه تراکنش دائمی نمی دهم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

به محض اجرای دستور تجزیه و تحلیل ((ANALYZE))، همان کوئری یک شناسه تراکنش دائمی به من می دهد. ببینید این برای ما چگونه تغییر کرده است. قبلاً این شناسه را نداشتم، اما اکنون آن را دارم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین در اینجا یک درخواست دیگر، یک معامله دیگر وجود دارد. شماره تراکنش مجازی 2/13 است. و اگر من یک شناسه تراکنش دائمی بخواهم، وقتی پرس و جو را اجرا کردم، آن را دریافت خواهم کرد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین، یک بار دیگر. ما یک شناسه تراکنش مجازی و یک شناسه تراکنش دائمی داریم. برای درک رفتار Postgres فقط این نکته را درک کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

به بخش سوم می رویم. در اینجا ما به سادگی انواع قفل های Postgres را بررسی می کنیم. زیاد جالب نیست بخش آخر بسیار جالب تر خواهد بود. اما ما باید موارد اساسی را در نظر بگیریم، زیرا در غیر این صورت متوجه نمی شویم که چه اتفاقی می افتد.

ما از طریق این بخش می گذریم، هر نوع قفل را بررسی می کنیم. و من نمونه هایی از نحوه نصب آنها، نحوه کار آنها را به شما نشان خواهم داد، من به شما چند جستار را نشان خواهم داد که می توانید از آنها برای مشاهده نحوه عملکرد قفل در Postgres استفاده کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

برای ایجاد یک پرس و جو و دیدن آنچه در Postgres اتفاق می افتد، باید پرس و جو را در نمای سیستم صادر کنیم. در این حالت pg_lock با رنگ قرمز مشخص می شود. Pg_lock یک جدول سیستمی است که به ما می گوید در حال حاضر از چه قفل هایی در Postgres استفاده می شود.

با این حال، برای من بسیار دشوار است که pg_lock را به تنهایی به شما نشان دهم زیرا بسیار پیچیده است. بنابراین من یک نمای ایجاد کردم که pg_locks را نشان می دهد. و همچنین کارهایی را برای من انجام می دهد که به من امکان می دهد بهتر بفهمم. یعنی قفل‌های من، جلسه خودم و غیره را حذف می‌کند. این فقط SQL استاندارد است و به شما امکان می‌دهد بهتر به شما نشان دهید که چه اتفاقی می‌افتد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

مشکل دیگر این است که این نمای بسیار گسترده است، بنابراین من باید یک دوم ایجاد کنم - lockview2.

باز کردن قفل Postgres Lock Manager. بروس مومجیان و ستون های بیشتری را از جدول به من نشان می دهد. و یکی دیگر که بقیه ستون ها را به من نشان می دهد. این بسیار پیچیده است، بنابراین من سعی کردم آن را به ساده ترین شکل ممکن ارائه کنم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین جدولی به نام Lockdemo ایجاد کردیم. و ما یک خط در آنجا ایجاد کردیم. این جدول نمونه ماست. و ما بخش هایی ایجاد خواهیم کرد تا نمونه هایی از قفل ها را به شما نشان دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین، یک ردیف، یک ستون. اولین نوع قفل ACCESS SHARE نام دارد. این کمترین محدودیت محدودیت است. این بدان معنی است که عملاً با سایر قفل ها در تضاد نیست.

و اگر بخواهیم قفل را به صراحت تعریف کنیم، دستور “lock table” را اجرا می کنیم. و بدیهی است که مسدود می شود، یعنی در حالت ACCESS SHARE جدول قفل را راه اندازی می کنیم. و اگر PSQL را در پس زمینه اجرا کنم، سپس جلسه دوم را از اولین جلسه خود به این ترتیب شروع می کنم. یعنی اینجا چیکار کنم؟ من به جلسه دیگری می روم و به آن می گویم "نمایش قفل را برای این درخواست به من نشان بده." و در اینجا من AccessShareLock را در این جدول دارم. این دقیقاً همان چیزی است که من درخواست کردم. و می گوید بلوک تعیین شده است. بسیار ساده.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

علاوه بر این، اگر به ستون دوم نگاه کنیم، چیزی در آنجا وجود ندارد. آنها خالی هستند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر دستور "SELECT" را اجرا کنم، این روش ضمنی (صریح) برای درخواست AccessShareLock است. بنابراین جدولم را آزاد می کنم و پرس و جو را اجرا می کنم و پرس و جو چندین ردیف را برمی گرداند. و در یکی از خطوط AccessShareLock را می بینیم. بنابراین، SELECT AccessShareLock را روی میز فراخوانی می کند. و تقریباً با هیچ چیز در تضاد نیست زیرا یک قفل سطح پایین است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر یک SELECT اجرا کنم و سه جدول مختلف داشته باشم چه می شود؟ قبلا فقط یک جدول را اجرا می کردم، اکنون سه جدول را اجرا می کنم: pg_class، pg_namespace و pg_attribute.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اکنون وقتی به پرس و جو نگاه می کنم، 9 AccessShareLocks را در سه جدول می بینم. چرا؟ سه جدول با رنگ آبی مشخص شده اند: pg_attribute، pg_class، pg_namespace. اما شما همچنین می توانید ببینید که تمام ایندکس هایی که از طریق این جداول تعریف می شوند دارای AccessShareLock نیز هستند.

و این قفلی است که عملاً با دیگران در تضاد نیست. و تنها کاری که انجام می دهد این است که ما را از تنظیم مجدد جدول در زمانی که آن را انتخاب می کنیم جلوگیری می کند. منطقی است. یعنی اگر جدولی را انتخاب کنیم در آن لحظه ناپدید می شود، پس این اشتباه است، بنابراین AccessShare یک قفل سطح پایین است که به ما می گوید "این جدول را در حالی که من کار می کنم رها نکنید". در اصل، این تمام کاری است که او انجام می دهد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

ROW SHARE - این قفل کمی متفاوت است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بیایید یک مثال بزنیم. روش SELECT ROW SHARE برای قفل کردن هر ردیف به صورت جداگانه. به این ترتیب هیچ کس نمی تواند آنها را حذف یا تغییر دهد در حالی که ما آنها را تماشا می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیانپس SHARE LOCK چه می کند؟ می بینیم که شناسه تراکنش 681 برای SELECT است. و این جالب است. اینجا چه اتفاقی افتاد؟ اولین باری که عدد را می بینیم در قسمت "قفل" است. شناسه تراکنش را می گیریم و می گوید در حالت انحصاری آن را مسدود می کند. تمام کاری که می کند این است که می گوید من یک ردیف دارم که از نظر فنی در جایی در جدول قفل شده است. اما دقیقا نمی گوید کجاست. کمی بعد با جزئیات بیشتری به این موضوع خواهیم پرداخت.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در اینجا می گوییم که قفل توسط ما استفاده می شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین، یک قفل انحصاری به صراحت می گوید که انحصاری است. و همچنین اگر یک ردیف را در این جدول حذف کنید، همانطور که می بینید این اتفاق خواهد افتاد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

SHARE EXCLUSIVE یک قفل طولانی تر است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این دستور تحلیلگر (ANALYZE) است که استفاده خواهد شد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

SHARE LOCK – می توانید به صراحت در حالت اشتراک گذاری قفل کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

شما همچنین می توانید یک شاخص منحصر به فرد ایجاد کنید. و در آنجا می توانید SHARE LOCK را ببینید که بخشی از آنهاست. و میز را قفل می کند و یک SHARE LOCK روی آن قرار می دهد.

به طور پیش‌فرض، SHARE LOCK در جدول به این معنی است که افراد دیگر می‌توانند جدول را بخوانند، اما هیچ‌کس نمی‌تواند آن را تغییر دهد. و این دقیقاً همان چیزی است که وقتی یک شاخص منحصر به فرد ایجاد می کنید اتفاق می افتد.

اگر من یک نمایه همزمان منحصربفرد ایجاد کنم، آنگاه نوع قفل متفاوتی خواهم داشت زیرا همانطور که به یاد دارید، استفاده از نمایه های همزمان نیاز قفل را کاهش می دهد. و اگر از یک قفل معمولی، یک نمایه معمولی استفاده کنم، بنابراین از نوشتن روی نمایه جدول در حین ایجاد آن جلوگیری می کنم. اگر من از یک شاخص همزمان استفاده کنم، باید از نوع دیگری از قفل استفاده کنم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

SHARE ROW انحصاری - مجدداً می توان آن را به صراحت (به طور صریح) تنظیم کرد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

یا می‌توانیم یک قانون ایجاد کنیم، به عنوان مثال، یک مورد خاص را در نظر بگیریم که در آن مورد استفاده قرار گیرد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

قفل انحصاری به این معنی است که هیچ کس دیگری نمی تواند جدول را تغییر دهد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در اینجا انواع قفل ها را می بینیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

برای مثال ACCESS EXCLUSIVE یک فرمان مسدود کننده است. به عنوان مثال، اگر شما انجام دهید CLUSTER table، پس این بدان معنی است که هیچ کس نمی تواند در آنجا بنویسد. و نه تنها خود جدول، بلکه شاخص ها را نیز قفل می کند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این صفحه دوم مسدودسازی ACCESS EXCLUSIVE است که دقیقاً آنچه را که در جدول مسدود می کند می بینیم. ردیف های جداول را قفل می کند که بسیار جالب است.

این تمام اطلاعات اولیه ای است که می خواستم ارائه دهم. در مورد قفل ها، در مورد شناسه تراکنش ها، در مورد شناسه تراکنش های مجازی، در مورد شناسه تراکنش های دائمی صحبت کردیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اکنون چند نمونه مسدودکننده را مرور خواهیم کرد. این جالب ترین قسمت است. ما به موارد بسیار جالب توجه خواهیم کرد. و هدف من در این ارائه این است که به شما درک بهتری از آنچه که Postgres در واقع انجام می دهد در زمانی که سعی می کند برخی چیزها را مسدود کند به شما ارائه دهم. من فکر می کنم او در مسدود کردن قطعات بسیار خوب است.

بیایید به چند نمونه خاص نگاه کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

ما با جداول و یک ردیف در یک جدول شروع می کنیم. وقتی چیزی را وارد می کنم، ExclusiveLock، شناسه تراکنش و ExclusiveLock روی میز نمایش داده می شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر دو ردیف دیگر وارد کنم چه اتفاقی می‌افتد؟ و حالا جدول ما سه ردیف دارد. و من یک ردیف را وارد کردم و این را به عنوان خروجی گرفتم. و اگر دو ردیف دیگر را وارد کنم، چه چیز عجیبی است؟ یک چیز عجیب در اینجا وجود دارد زیرا من سه ردیف به این جدول اضافه کرده ام، اما هنوز دو ردیف در جدول قفل دارم. و این اساساً رفتار اساسی Postgres است.

بسیاری از مردم فکر می کنند که اگر در یک پایگاه داده 100 ردیف را قفل کنید، باید 100 ورودی قفل ایجاد کنید. اگر 1 ردیف را به طور همزمان مسدود کنم، به 000 چنین پرس و جو نیاز دارم. و اگر برای بلاک کردن به یک میلیون یا یک میلیارد نیاز دارم. اما اگر این کار را انجام دهیم، خیلی خوب کار نخواهد کرد. اگر از سیستمی استفاده کرده‌اید که ورودی‌های مسدودکننده را برای هر ردیف جداگانه ایجاد می‌کند، می‌بینید که این کار پیچیده است. زیرا باید فوراً یک جدول قفل تعریف کنید که می تواند سرریز شود، اما Postgres این کار را انجام نمی دهد.

و آنچه واقعاً در مورد این اسلاید مهم است این است که به وضوح نشان می دهد که سیستم دیگری وجود دارد که در داخل MVCC اجرا می شود که ردیف های جداگانه را قفل می کند. بنابراین وقتی میلیاردها ردیف را قفل می کنید، Postgres یک میلیارد دستور قفل جداگانه ایجاد نمی کند. و این تاثیر بسیار خوبی بر بهره وری دارد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در مورد به روز رسانی چطور؟ من اکنون ردیف را به روز می کنم و می بینید که دو عملیات مختلف را همزمان انجام داده است. در همان زمان جدول را قفل کرد، اما شاخص را نیز قفل کرد. و او باید ایندکس را قفل می کرد زیرا محدودیت های منحصر به فردی در این جدول وجود دارد. و ما می خواهیم مطمئن شویم که هیچ کس آن را تغییر نمی دهد، بنابراین آن را مسدود می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر بخواهم دو ردیف را به روز کنم چه اتفاقی می افتد؟ و می بینیم که او نیز همین رفتار را دارد. ما دو برابر بیشتر به روز رسانی انجام می دهیم، اما دقیقاً همان تعداد خطوط قفل.

اگر می‌پرسید Postgres چگونه این کار را انجام می‌دهد، باید به صحبت‌های من در MVCC گوش دهید تا بدانید Postgres چگونه این خطوط را که تغییر می‌دهد به صورت داخلی علامت‌گذاری می‌کند. و Postgres راهی برای انجام این کار دارد، اما این کار را در سطح قفل کردن میز انجام نمی دهد، آن را در سطح پایین تر و کارآمدتر انجام می دهد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر بخواهم چیزی را حذف کنم چه؟ اگر مثلاً یک ردیف را حذف کنم و هنوز دو ورودی مسدودکننده خود را داشته باشم و حتی اگر بخواهم همه آنها را حذف کنم، باز هم هستند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و مثلاً من می خواهم 1 خط را وارد کنم و سپس 000 خط را حذف یا اضافه کنم، سپس آن خطوط فردی را که اضافه یا تغییر می دهم، اینجا ثبت نمی شوند. آنها در سطح پایین تری در خود سریال نوشته شده اند. و در طول سخنرانی MVCC من در این مورد به تفصیل صحبت کردم. اما هنگام تجزیه و تحلیل قفل ها بسیار مهم است که مطمئن شوید که در سطح جدول قفل شده اید و نمی بینید که ردیف های جداگانه چگونه در اینجا ثبت می شوند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در مورد مسدود کردن صریح چطور؟

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر روی refresh کلیک کنم، دو ردیف قفل شده‌ام. و اگر همه آنها را انتخاب کنم و روی "به روز رسانی همه جا" کلیک کنم، هنوز دو رکورد مسدود کننده دارم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

ما رکوردهای جداگانه ای برای هر ردیف جداگانه ایجاد نمی کنیم. از آنجا که در این صورت بهره وری کاهش می یابد، ممکن است مقدار زیادی از آن وجود داشته باشد. و ممکن است در موقعیت ناخوشایندی قرار بگیریم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و همین کار را، اگر به اشتراک بگذاریم، می توانیم همه آن را 30 بار انجام دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

جدول خود را بازیابی می کنیم، همه چیز را حذف می کنیم، سپس یک ردیف را دوباره وارد می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

یکی دیگر از رفتارهایی که در Postgres مشاهده می کنید که بسیار شناخته شده و رفتار مطلوب است این است که می توانید یک آپدیت یا یک انتخاب انجام دهید. و شما می توانید این کار را همزمان انجام دهید. و select does not block update و همون چیز در جهت مخالف. ما به خواننده می گوییم نویسنده را بلاک نکند و نویسنده هم خواننده را مسدود نکرده است.

من نمونه ای از این را به شما نشان می دهم. من الان انتخاب خواهم کرد. سپس INSERT را انجام می دهیم. و سپس می توانید - 694 را ببینید. می توانید شناسه تراکنشی که این درج را انجام داده است را مشاهده کنید. و اینطوری کار می کند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر اکنون به ID Backend خود نگاه کنم، اکنون 695 است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و من می توانم 695 را ببینم که در جدول من ظاهر می شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر اینجا را به این شکل به روز کنم، یک مورد متفاوت دریافت می کنم. در این مورد، 695 یک قفل انحصاری است و به روز رسانی نیز همین رفتار را دارد، اما هیچ تضادی بین آنها وجود ندارد، که کاملا غیر معمول است.

و می بینید که در بالا ShareLock و در پایین ExclusiveLock است. و هر دو معامله انجام شد.

و شما باید به صحبت های من در MVCC گوش دهید تا بفهمید چگونه این اتفاق می افتد. اما این یک مثال است که می توانید آن را همزمان انجام دهید، یعنی یک SELECT و یک UPDATE را همزمان انجام دهید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بیایید ریست کنیم و یک عملیات دیگر انجام دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر بخواهید دو آپدیت را به طور همزمان در یک ردیف اجرا کنید، مسدود می شود. و به یاد داشته باشید، گفتم که خواننده نویسنده را مسدود نمی کند و نویسنده خواننده را مسدود نمی کند، اما یک نویسنده نویسنده دیگری را مسدود می کند. یعنی نمی‌توانیم دو نفر یک ردیف را همزمان آپدیت کنند. باید صبر کنید تا یکی از آنها تمام شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و برای نشان دادن این موضوع، به جدول Lockdemo نگاه می کنم. و ما به یک ردیف نگاه خواهیم کرد. در هر تراکنش 698.

ما این را به 2 به روز کردیم. 699 اولین آپدیت است. و موفقیت آمیز بود یا در حال تعلیق است و منتظر تایید یا لغو است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اما به چیز دیگری نگاه کنید - 2/51 اولین تراکنش ما است، اولین جلسه ما. 3/112 دومین درخواستی است که از بالا آمده و آن مقدار را به 3 تغییر داده است. و اگر متوجه شده باشید، بالا خودش را قفل کرد که 699 است. اما 3/112 قفل را اعطا نکرد. ستون Lock_mode می گوید که منتظر چه چیزی است. انتظار 699 را دارد. و اگر به جایی که 699 است نگاه کنید، بالاتر است. و جلسه اول چه کرد؟ او یک قفل انحصاری در شناسه تراکنش خود ایجاد کرد. Postgres این کار را انجام می دهد. شناسه تراکنش خود را مسدود می کند. و اگر می‌خواهید منتظر بمانید تا کسی تأیید یا لغو کند، باید منتظر بمانید تا معامله‌ای در حال تعلیق باشد. و به همین دلیل است که می توانیم یک خط عجیب را ببینیم.

بیایید دوباره نگاه کنیم. در سمت چپ شناسه پردازش خود را می بینیم. در ستون دوم شناسه تراکنش مجازی خود را می بینیم و در ستون سوم lock_type را می بینیم. این یعنی چی؟ اساساً چیزی که می گوید این است که شناسه تراکنش را مسدود می کند. اما توجه کنید که تمام ردیف‌های پایین می‌گویند رابطه. و بنابراین شما دو نوع قفل روی میز دارید. یک قفل رابطه وجود دارد. و سپس مسدود کردن تراکنش، جایی که شما به تنهایی بلاک می کنید، دقیقاً همان چیزی است که در ردیف اول یا در انتهای آن اتفاق می افتد، جایی که تراکنش در آن قرار دارد، جایی که منتظر می مانیم تا 699 عملیات خود را به پایان برساند.

ببینم اینجا چی میشه و در اینجا دو اتفاق به طور همزمان رخ می دهد. شما به قفل شناسه تراکنش در ردیف اول نگاه می کنید که خود را قفل می کند. و خودش را مسدود می کند تا مردم را منتظر بسازد.

اگر به خط 6 نگاه کنید، همان ورودی اول است. و بنابراین تراکنش 699 مسدود می شود. 700 هم خودش قفل میشه. و سپس در ردیف پایین خواهید دید که ما منتظر 699 هستیم تا عملیات خود را به پایان برساند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و در lock_type، تاپل اعداد را می بینید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

می توانید ببینید که 0/10 است. و این شماره صفحه و همچنین افست این ردیف خاص است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و می بینید که وقتی به روز می کنیم 0/11 می شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اما در واقعیت 0/10 است، زیرا انتظار برای این عملیات وجود دارد. ما این فرصت را داریم که ببینیم این سریالی است که منتظر تایید آن هستم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

هنگامی که آن را تأیید کردیم و commit را فشار دادیم، و هنگامی که به روز رسانی به پایان رسید، این چیزی است که دوباره دریافت می کنیم. تراکنش 700 تنها قفل است که منتظر هیچ کس دیگری نیست زیرا متعهد شده است. فقط منتظر می ماند تا تراکنش کامل شود. وقتی 699 تمام شد، دیگر منتظر چیزی نیستیم. و اکنون تراکنش 700 می گوید که همه چیز خوب است، که تمام قفل های مورد نیاز خود را روی همه میزهای مجاز دارد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و برای پیچیده‌تر کردن این موضوع، نمای دیگری ایجاد می‌کنیم که این بار سلسله مراتبی را برای ما فراهم می‌کند. من از شما انتظار ندارم که این درخواست را درک کنید. اما این به ما دید واضح تری از آنچه در حال وقوع است می دهد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این یک نمای بازگشتی است که بخش دیگری نیز دارد. و سپس همه چیز را دوباره با هم جمع می کند. بیایید از این استفاده کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر سه به‌روزرسانی همزمان انجام دهیم و بگوییم که ردیف اکنون سه است، چه می‌شود. و ما 3 را به 4 تغییر می دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و در اینجا 4. و شناسه تراکنش 702 را می بینیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و سپس 4 را به 5 و 5 را به 6 و 6 را به 7 تغییر می دهم. و تعدادی از افرادی را که منتظر پایان این تراکنش خواهند بود صف آرایی خواهم کرد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و همه چیز روشن می شود. ردیف اول چیست؟ این 702 است. این شناسه تراکنش است که در ابتدا این مقدار را تنظیم کرده است. در ستون Granted من چه نوشته شده است؟ من نمرات دارم f. اینها به روز رسانی های من هستند که (5، 6، 7) قابل تایید نیستند زیرا منتظر پایان شناسه تراکنش 702 هستیم. در آنجا ما مسدود کردن شناسه تراکنش را داریم. و این منجر به 5 قفل شناسه تراکنش می شود.

و اگر به 704، در 705 نگاه کنید، هنوز چیزی در آنجا نوشته نشده است، زیرا آنها هنوز نمی دانند چه خبر است. آنها به سادگی می نویسند که نمی دانند چه اتفاقی دارد می افتد. و آنها فقط به خواب می روند زیرا منتظر هستند تا کسی کار را تمام کند و وقتی فرصتی برای تغییر ردیف وجود دارد از خواب بیدار شوند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این چیزی است که به نظر می رسد. معلوم است که همه منتظر خط دوازدهم هستند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این چیزی است که ما اینجا دیدیم. اینجا 0/12 است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین هنگامی که اولین تراکنش تایید شد، می توانید در اینجا ببینید که سلسله مراتب چگونه کار می کند. و اکنون همه چیز روشن می شود. همشون پاک میشن و در واقع هنوز منتظرند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این چیزی است که اتفاق می افتد. 702 متعهد می شود. و اکنون 703 این قفل ردیف را دریافت می کند و سپس 704 شروع به انتظار برای 703 می کند. و 705 نیز منتظر این است. و وقتی همه اینها کامل شد، خودشان را تمیز می کنند. و من می خواهم به این نکته اشاره کنم که همه در صف هستند. و این بسیار شبیه به وضعیتی در ترافیک است که همه منتظر اولین ماشین هستند. اولین ماشین می ایستد و همه در یک صف طولانی صف می کشند. سپس حرکت می کند، سپس ماشین بعدی می تواند جلو برود و بلوک خود را بگیرد و غیره.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر این به اندازه کافی برای شما پیچیده به نظر نمی رسید، اکنون در مورد بن بست ها با شما صحبت خواهیم کرد. من نمی دانم کدام یک از شما با آنها برخورد کرده اید. این یک مشکل نسبتا رایج در سیستم های پایگاه داده است. اما بن بست زمانی است که یک جلسه منتظر جلسه دیگری برای انجام کاری است. و در این لحظه جلسه دیگری منتظر اولین جلسه برای انجام کاری است.

و مثلاً اگر ایوان بگوید: "چیزی به من بده" و من بگویم: "نه، فقط در صورتی آن را به تو می دهم که چیز دیگری به من بدهی." و او می گوید: "نه، اگر به من ندهی به تو نمی دهم." و در نهایت در یک وضعیت بن بست قرار می گیریم. من مطمئنم که ایوان این کار را نمی کند، اما شما این معنی را درک می کنید که ما دو نفر داریم که می خواهند چیزی را به دست آورند و تا زمانی که طرف مقابل آن چیزی را که می خواهند به آنها ندهد حاضر نیستند آن را پس بدهند. و هیچ راه حلی وجود ندارد.

و اساسا، پایگاه داده شما باید این را شناسایی کند. و سپس باید یکی از جلسات را حذف یا ببندید، زیرا در غیر این صورت برای همیشه در آنجا باقی خواهند ماند. و ما آن را در پایگاه داده ها، در سیستم عامل ها می بینیم. و در همه جاهایی که فرآیندهای موازی داریم، ممکن است این اتفاق بیفتد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اکنون دو بن بست نصب می کنیم. 50 و 80 میزاریم ردیف اول از 50 به 50 آپدیت میکنم شماره تراکنش 710 رو میگیرم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و سپس 80 را به 81 و 50 را به 51 تغییر می دهم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و این چیزی است که به نظر خواهد رسید. و بنابراین 710 یک ردیف مسدود شده است و 711 منتظر تایید است. این را وقتی به روز کردیم دیدیم. 710 صاحب سری ماست. و 711 منتظر 710 می ماند تا تراکنش کامل شود.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و حتی می گوید که بن بست در کدام ردیف رخ می دهد. و اینجاست که شروع به عجیب شدن می کند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اکنون 80 به 80 را به روز می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اینجاست که بن بست ها شروع می شود. 710 منتظر پاسخ 711 است و 711 منتظر 710 است. و این پایان خوبی نخواهد داشت. و هیچ راهی برای خروج از این وجود ندارد. و از یکدیگر انتظار پاسخ خواهند داشت.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و فقط شروع به به تاخیر انداختن همه چیز می کند. و ما این را نمی خواهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و Postgres راه هایی برای توجه به این اتفاق دارد. و وقتی این اتفاق می افتد، این خطا را دریافت می کنید. و از اینجا مشخص می شود که فلان فرآیند منتظر یک SHARE LOCK از یک فرآیند دیگر است، یعنی توسط فرآیند 711 مسدود شده است. و آن فرآیند منتظر بود تا یک SHARE LOCK روی شناسه تراکنش فلان داده شود و توسط فلان فرآیند مسدود شد. بنابراین، در اینجا یک وضعیت بن بست وجود دارد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

آیا بن بست های سه جانبه وجود دارد؟ آیا امکان دارد؟ آره.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این اعداد را در جدول وارد می کنیم. ما 40 را به 40 تغییر می دهیم، بلوک را انجام می دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

ما 60 را به 61، 80 را به 81 تغییر می دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و بعد 80 عوض می کنیم و بعد بوم می کنیم!

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و 714 اکنون منتظر 715 است. 716 در انتظار 715 است. و هیچ کاری نمی توان در مورد آن انجام داد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اینجا دیگر دو نفر نیستند، از قبل سه نفر اینجا هستند. من از شما چیزی می خواهم، این یکی از شخص سوم چیزی می خواهد و نفر سوم از من چیزی می خواهد. و ما در نهایت در یک انتظار سه جانبه قرار می گیریم زیرا همه ما منتظر هستیم تا طرف مقابل کاری را که باید انجام دهد تکمیل کند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و Postgres می داند در کدام ردیف این اتفاق می افتد. و به این ترتیب پیغام زیر را به شما می دهد که نشان می دهد مشکلی دارید که سه ورودی یکدیگر را مسدود می کنند. و در اینجا هیچ محدودیتی وجود ندارد. این ممکن است زمانی باشد که 20 ورودی یکدیگر را مسدود کنند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

مشکل بعدی سریال شدن است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

اگر قفل سریالی خاص.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و به 719 برمی گردیم. خروجی آن کاملاً عادی است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و می توانید کلیک کنید تا تراکنش از سریال قابل سریال سازی باشد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و متوجه می‌شوید که اکنون نوع دیگری از قفل SA دارید - این به معنای قابل سریال‌سازی است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و بنابراین ما یک نوع قفل جدید به نام SARieadLock داریم که یک قفل سریال است و به شما امکان می دهد سریال ها را وارد کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و همچنین می توانید شاخص های منحصر به فرد را وارد کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در این جدول شاخص های منحصر به فردی داریم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بنابراین اگر عدد 2 را در اینجا قرار دهم، پس من یک عدد 2 دارم. اما در بالا، 2 دیگر را وارد کردم. و می توانید ببینید که 721 یک قفل انحصاری دارد. اما اکنون 722 منتظر 721 است تا عملیات خود را کامل کند زیرا تا زمانی که نداند چه اتفاقی برای 2 می افتد نمی تواند 721 را وارد کند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر معامله فرعی انجام دهیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

در اینجا ما 723 داریم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و اگر نقطه را ذخیره کنیم و سپس آن را به روز کنیم، یک شناسه تراکنش جدید دریافت می کنیم. این یکی دیگر از الگوهای رفتاری است که باید از آن آگاه باشید. اگر این را برگردانیم، شناسه تراکنش از بین می رود. 724 می رود. اما الان 725 داریم.

پس من در اینجا می خواهم چه کار کنم؟ من سعی می‌کنم نمونه‌هایی از قفل‌های غیرعادی را که ممکن است پیدا کنید به شما نشان دهم: چه قفل‌های قابل سریال‌سازی یا SAVEPOINT، اینها انواع مختلفی از قفل‌ها هستند که در جدول قفل ظاهر می‌شوند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این ایجاد قفل های صریح (صریح) است که دارای pg_advisory_lock هستند.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و می بینید که نوع مسدود کردن به عنوان مشاوره درج شده است. و در اینجا به رنگ قرمز می گوید "مشاوره". و می توانید همزمان با pg_advisory_unlock اینگونه مسدود کنید.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و در خاتمه، می‌خواهم یک چیز شگفت‌انگیز دیگر را به شما نشان دهم. من یک نمای دیگر ایجاد خواهم کرد. اما من به جدول pg_locks با جدول pg_stat_activity ملحق خواهم شد. و چرا من می خواهم این کار را انجام دهم؟ زیرا این به من امکان می دهد تمام جلسات فعلی را ببینم و ببینم دقیقاً منتظر چه نوع قفل هایی هستند. و این زمانی که جدول قفل و جدول پرس و جو را کنار هم قرار می دهیم بسیار جالب است.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و در اینجا pg_stat_view را ایجاد می کنیم.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و ردیف را یکی یکی به روز می کنیم. و در اینجا 724 را می بینیم. و سپس ردیف خود را به سه به روز می کنیم. و الان اینجا چی میبینی؟ اینها درخواست هستند، یعنی شما کل لیست درخواست هایی را می بینید که در ستون سمت چپ لیست شده اند. و سپس در سمت راست می توانید انسدادها و آنچه را که ایجاد می کنند را ببینید. و می تواند برای شما واضح تر باشد تا مجبور نباشید هر بار به هر جلسه برگردید و ببینید که آیا نیاز به پیوستن به آن دارید یا خیر. آنها این کار را برای ما انجام می دهند.

یکی دیگر از ویژگی هایی که بسیار مفید است این است pg_blocking_pids. احتمالاً هرگز نام او را نشنیده اید. او چه کار می کند؟ این به ما امکان می‌دهد بگوییم که برای این جلسه 11740 چه شناسه‌های فرآیند خاصی را انتظار می‌کشد. و می توانید ببینید که 11740 منتظر 724 است. و 724 در بالای صفحه است. و 11306 شناسه فرآیند شماست. در اصل، این تابع از جدول قفل شما عبور می کند. و من می دانم که کمی پیچیده است، اما شما می توانید آن را درک کنید. اساساً این تابع از طریق جدول قفل می گذرد و سعی می کند پیدا کند که در کجا به این شناسه فرآیند قفل هایی داده می شود که منتظر است. و همچنین سعی می کند بفهمد که فرآیندی که در انتظار قفل است دارای کدام شناسه پردازش است. بنابراین می توانید این تابع را اجرا کنید pg_blocking_pids.

و این می تواند بسیار مفید باشد. ما فقط این را در نسخه 9.6 اضافه کردیم، بنابراین این ویژگی تنها 5 سال از عمر آن می گذرد، اما بسیار بسیار مفید است. و همین امر در مورد درخواست دوم نیز صدق می کند. دقیقاً آنچه را که باید ببینیم را نشان می دهد.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

این چیزی است که می خواستم در مورد آن با شما صحبت کنم. و همانطور که انتظار داشتم، ما تمام وقت خود را صرف کردیم زیرا اسلایدهای زیادی وجود داشت. و اسلایدها برای دانلود در دسترس هستند. می خواهم از حضور شما در اینجا تشکر کنم. من مطمئن هستم که از بقیه کنفرانس لذت خواهید برد، بسیار متشکرم!

پرسش:

به عنوان مثال، اگر من سعی می کنم ردیف ها را به روز کنم، و جلسه دوم سعی می کند کل جدول را حذف کند. تا جایی که من متوجه شدم باید چیزی شبیه قفل قصد وجود داشته باشد. آیا چنین چیزی در Postgres وجود دارد؟

باز کردن قفل Postgres Lock Manager. بروس مومجیان

بیایید به همان ابتدا برگردیم. ممکن است به یاد داشته باشید که وقتی کاری انجام می دهید، برای مثال زمانی که یک SELECT انجام می دهید، ما یک AccessShareLock صادر می کنیم. و این مانع از افتادن میز می شود. بنابراین، اگر شما، برای مثال، می خواهید یک ردیف را در یک جدول به روز کنید یا یک ردیف را حذف کنید، در آن صورت کسی نمی تواند کل جدول را همزمان حذف کند زیرا شما این AccessShareLock را روی کل جدول و روی ردیف نگه داشته اید. و پس از اتمام کار، آنها می توانند آن را حذف کنند. اما در حالی که شما مستقیماً چیزی را در آنجا تغییر می دهید، آنها قادر به انجام آن نخواهند بود.

بیایید دوباره آن را انجام دهیم. بیایید به مثال حذف برویم. و می بینید که چگونه یک قفل انحصاری در ردیف بالای کل جدول وجود دارد.

این شبیه به قفل منحصر به فرد خواهد بود، درست است؟

بله، به نظر می رسد. من می فهمم در مورد چه چیزی صحبت می کنید. شما می گویید که اگر من یک SELECT انجام دهم، سپس یک ShareExclusive داشته باشم و سپس آن را Row Exclusive کنم، آیا مشکلی ایجاد می شود؟ اما در کمال تعجب این مشکلی ایجاد نمی کند. این به نظر افزایش درجه قفل است، اما در اصل من قفلی دارم که از حذف جلوگیری می کند. و حالا، وقتی این قفل را قدرتمندتر می کنم، باز هم از حذف جلوگیری می کند. پس اینطور نیست که من بروم بالا. یعنی وقتی در سطح پایین‌تری هم بود از این اتفاق جلوگیری کرد، بنابراین وقتی سطح آن را بالا می‌برم همچنان از حذف جدول جلوگیری می‌کند.

من می فهمم در مورد چه چیزی صحبت می کنید. در اینجا هیچ موردی برای تشدید قفل وجود ندارد، جایی که شما سعی می کنید از یک قفل صرف نظر کنید تا قفل قوی تر معرفی کنید. در اینجا فقط این پیشگیری را در سراسر صفحه افزایش می دهد، بنابراین هیچ درگیری ایجاد نمی کند. اما سوال خوبی است. خیلی ممنون که این را پرسیدید!

برای جلوگیری از بن بست زمانی که جلسات زیادی داریم، تعداد کاربران زیادی داریم، چه کاری باید انجام دهیم؟

Postgres به طور خودکار متوجه موقعیت های بن بست می شود. و به طور خودکار یکی از جلسات را حذف می کند. تنها راه برای جلوگیری از مسدود شدن مرده، مسدود کردن افراد به همان ترتیب است. بنابراین وقتی به برنامه خود نگاه می کنید، اغلب دلیل بن بست هاست... بیایید تصور کنیم که من می خواهم دو چیز مختلف را مسدود کنم. یک برنامه جدول 1 را قفل می کند و برنامه دیگری 2 و سپس جدول 1 را قفل می کند. و ساده ترین راه برای جلوگیری از بن بست این است که به برنامه خود نگاه کنید و سعی کنید مطمئن شوید که قفل شدن در همه برنامه ها به یک ترتیب انجام می شود. و این معمولاً 80 درصد مشکلات را برطرف می کند، زیرا همه نوع افراد این برنامه ها را می نویسند. و اگر آنها را به همان ترتیب مسدود کنید، با وضعیت بن بست مواجه نمی شوید.

از عملکرد شما بسیار متشکرم! شما در مورد vacuum full صحبت کردید و اگر درست متوجه شدم، vacuum full ترتیب رکوردها را در ذخیره سازی جداگانه مخدوش می کند، بنابراین آنها رکوردهای فعلی را بدون تغییر نگه می دارند. چرا vacuum full دسترسی انحصاری قفل را می گیرد و چرا با عملیات نوشتن در تضاد است؟

این سوال خوبی است. دلیل آن این است که خلاء کامل جدول را می گیرد. و ما اساساً در حال ایجاد یک نسخه جدید از جدول هستیم. و جدول جدید خواهد بود. به نظر می رسد که این یک نسخه کاملاً جدید از جدول خواهد بود. و مشکل این است که وقتی این کار را انجام می‌دهیم، نمی‌خواهیم مردم آن را بخوانند، زیرا به آنها نیاز داریم تا جدول جدید را ببینند. و بنابراین این به سوال قبلی مرتبط است. اگر می‌توانستیم همزمان بخوانیم، نمی‌توانیم آن را جابه‌جا کنیم و مردم را به یک جدول جدید هدایت کنیم. ما باید منتظر بمانیم تا همه خواندن این جدول را به پایان برسانند، و بنابراین اساساً یک موقعیت انحصاری قفل است.
ما فقط می گوییم که از ابتدا قفل می کنیم زیرا می دانیم که در نهایت به یک قفل انحصاری نیاز داریم تا همه را به نسخه جدید منتقل کنیم. بنابراین ما به طور بالقوه می توانیم این را حل کنیم. و ما این کار را با نمایه سازی همزمان انجام می دهیم. اما انجام این کار بسیار دشوارتر است. و این بسیار به سوال قبلی شما در مورد lock exclusive مربوط می شود.

آیا می توان تایم اوت قفل را به Postgres اضافه کرد؟ در اوراکل، می‌توانم مثلاً «انتخاب برای به‌روزرسانی» را بنویسم و ​​قبل از به‌روزرسانی 50 ثانیه صبر کنم. برای برنامه خوب بود اما در Postgres یا باید فوراً این کار را انجام دهم و اصلاً منتظر نمانم یا تا مدتی صبر کنم.

بله، شما می توانید یک بازه زمانی در قفل های خود، در قفل های خود انتخاب کنید. شما همچنین می توانید دستور no way را صادر کنید، که اگر نتوانید فورا قفل را دریافت کنید... بنابراین، یا یک مهلت قفل یا چیز دیگری که به شما امکان انجام این کار را می دهد. این کار در سطح نحوی انجام نمی شود. این به عنوان یک متغیر در سرور انجام می شود. گاهی اوقات نمی توان از این استفاده کرد.

آیا می توانید اسلاید 75 را باز کنید؟

بله.

باز کردن قفل Postgres Lock Manager. بروس مومجیان

و سوال من به شرح زیر است. چرا هر دو فرآیند به روز رسانی انتظار 703 را دارند؟

و این یک سوال عالی است. اتفاقاً من نمی فهمم چرا Postgres این کار را می کند. اما وقتی 703 ساخته شد، انتظار 702 را داشت. و وقتی 704 و 705 ظاهر شدند، به نظر می‌رسد که آنها نمی‌دانند چه انتظاری دارند زیرا هنوز چیزی در آنجا وجود ندارد. و Postgres این کار را به این صورت انجام می‌دهد: وقتی نمی‌توانید قفلی دریافت کنید، می‌نویسد "در مورد شما چه فایده‌ای دارد؟"، زیرا شما از قبل منتظر کسی هستید. بنابراین ما فقط اجازه می دهیم در هوا معلق بماند، اصلاً آن را به روز نمی کند. اما اینجا چه اتفاقی افتاد؟ به محض اینکه 702 فرآیند را تکمیل کرد و 703 قفل خود را دریافت کرد، سیستم برگشت. و او گفت که اکنون دو نفر داریم که منتظرند. و سپس بیایید آنها را با هم به روز کنیم. و اجازه دهید نشان دهیم که هر دو منتظر هستند.

من نمی دانم چرا Postgres این کار را می کند. اما یک مشکل به نام f…. به نظر من این یک اصطلاح در روسی نیست. این زمانی است که همه منتظر یک قلعه هستند، حتی اگر 20 مقام منتظر قلعه باشند. و ناگهان همه در یک زمان از خواب بیدار می شوند. و همه شروع به واکنش می کنند. اما سیستم باعث می شود که همه منتظر 703 باشند. زیرا همه آنها منتظر هستند و ما بلافاصله همه آنها را ردیف می کنیم. و اگر هر درخواست جدید دیگری ظاهر شود که بعد از این ایجاد شده است، مثلاً 707، دوباره خالی خواهد بود.

و به نظر من این کار انجام می شود تا بتوانیم بگوییم در این مرحله 702 منتظر 703 است و همه کسانی که بعد از آن می آیند هیچ ورودی در این زمینه نخواهند داشت. اما به محض رفتن اولین پیشخدمت، همه کسانی که در آن لحظه قبل از به روز رسانی منتظر بودند، همان رمز را دریافت می کنند. و بنابراین من فکر می کنم این کار انجام می شود تا بتوانیم به ترتیب پردازش کنیم تا به درستی سفارش داده شوند.

من همیشه به این به عنوان یک پدیده نسبتاً عجیب نگاه می کردم. زیرا در اینجا، برای مثال، ما اصلاً آنها را فهرست نمی کنیم. اما به نظر من هر بار که قفل جدیدی می دهیم، به همه کسانی که در حال انتظار هستند نگاه می کنیم. سپس همه آنها را ردیف می کنیم. و سپس هر مورد جدیدی که وارد می شود فقط زمانی وارد صف می شود که پردازش شخص بعدی به پایان برسد. سوال خیلی خوبیه خیلی ممنون از سوال شما!

به نظر من وقتی 705 انتظار 704 را داشته باشد بسیار منطقی تر است.

اما مشکل اینجاست. از نظر فنی، می توانید یکی یا دیگری را بیدار کنید. و بنابراین ما یکی یا دیگری را بیدار خواهیم کرد. اما در سیستم چه اتفاقی می افتد؟ می توانید ببینید که چگونه 703 در همان بالا شناسه تراکنش خود را مسدود کرده است. Postgres اینگونه کار می کند. و 703 توسط شناسه تراکنش خودش مسدود می شود، بنابراین اگر کسی بخواهد منتظر بماند، منتظر 703 می شود. و در اصل 703 کامل می شود. و تنها پس از اتمام آن یکی از فرآیندها بیدار می شود. و ما نمی دانیم که این روند دقیقاً چه خواهد بود. سپس همه چیز را به تدریج پردازش می کنیم. اما مشخص نیست که کدام فرآیند ابتدا بیدار می شود، زیرا ممکن است هر یک از این فرآیندها باشد. در اصل، ما یک زمانبندی داشتیم که می گفت اکنون می توانیم هر یک از این فرآیندها را بیدار کنیم. ما فقط یکی را به صورت تصادفی انتخاب می کنیم. بنابراین هر دوی آنها باید مورد توجه قرار گیرند زیرا ما می توانیم هر یک از آنها را بیدار کنیم.

و مشکل این است که ما CP-infinity داریم. و بنابراین، کاملاً محتمل است که بتوانیم فرد بعدی را بیدار کنیم. و اگر به عنوان مثال، فرد بعدی را بیدار کنیم، منتظر کسی هستیم که به تازگی بلوک را دریافت کرده است، بنابراین تعیین نمی کنیم که دقیقاً چه کسی ابتدا بیدار شود. ما به سادگی چنین وضعیتی را ایجاد می کنیم و سیستم آنها را به ترتیب تصادفی بیدار می کند.

وجود دارد مقالاتی در مورد قفل توسط ایگور روگوف. ببینید، آنها نیز جالب و مفید هستند. موضوع، البته، به طرز وحشتناکی پیچیده است. خیلی ممنون، بروس!

منبع: www.habr.com

اضافه کردن نظر