WIUNIX ACADEMY
چرا ALTER در MySQL با LOCK=NONE هم منتظر میماند؟
روی یک جدول کوچک آزمایشی ببینید تراکنشِ فقطخواندنی چگونه ساخت ایندکس آنلاین را معطل میکند، طرفین انتظار را پیدا کنید و بدون قطع کورِ اتصالها علت انتظار را روشن کنید.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من3 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
در سه نشست جدا، نگهداشتن قفل تعریف جدول و انتظار DDL را بازسازی کنید؛ پس از پایان تراکنش خودتان، ساخت ایندکس را بررسی و فقط تغییر آزمایشی را برگردانید.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای مستند برای Ubuntu، Debian و خانوادهٔ Red Hat؛ محصول و کلاینت سازگار باید از قبل نصب باشند. محدودیت هر شاخه در گام نخست آمده است. فرمانها هنگام نگارش روی سرویس واقعی اجرا نشدهاند.
قبل از شروع
- سرور جداگانهٔ MySQL 8.4 با InnoDB، performance_schema و sys قابلدسترسی؛ جدول اصلی برنامه انتخاب نمیشود.
- فایل خصوصی اتصال با TLS و حساب مجازِ ساخت schema آزمایشی، سه ترمینال مستقل و نقش مشاهدهٔ لازم برای نشست C.
- نام schema تازه و فرصت نظارت بر انتظار محدود؛ هیچ اتصال نامرتبطی قطع و هیچ تنظیم سراسری سرور تغییر داده نمیشود.
آنلاینبودن، همهٔ قفلها را حذف نمیکند
LOCK=NONE میتواند همزمانی خواندن و نوشتن داده را در طول یک عملیات مجاز بداند، اما تغییر تعریف جدول هنوز به قفل فراداده نیاز دارد. حتی تراکنشی که فقط جدول را خوانده، ممکن است این قفل را تا پایان تراکنش نگه دارد.
در نتیجه ALTER منتظر میماند و گاهی درخواستهای بعدی نیز پشت آن صف میکشند. اینجا بخش مسدودکننده و منتظر را روی یک جدول تازهٔ سهردیفی میبینیم؛ زنجیرهٔ کامل بار برنامه را شبیهسازی نمیکنیم. در پایان نیز timeout فراداده را از انتظار قفل ردیف جدا میکنیم.
این مثال مخصوص MySQL 8.4 است
سرور آزمایش باید MySQL 8.4 و موتور جدول InnoDB باشد. نام الگوریتمهای DDL و جدولهای تشخیص در MariaDB الزاماً همین معنا و رفتار را ندارند؛ نسخهها را از روی نام مشابه یکی فرض نکنید.
اتصال امن و حسابها از قبل آمادهاند. این مقاله نصب، تغییر replication یا مهاجرت جدول برنامه را انجام نمیدهد. سه نشست مستقل به همان سرور آزمایشی وصل میشوند و فقط روی جدول ساختهشدهٔ همین تمرین کار میکنند.
یک schema تازه و زمان انتظار محدود انتخاب کنید
فرم فقط مسیر فایل اتصال، نام schema تازه و ثانیهٔ انتظار را میگیرد. فایل اتصال باید از قبل میزبان، حساب و TLS درست داشته باشد و فقط در دسترس مالک مجاز باشد؛ گذرواژه را در صفحه وارد نکنید. مقدارهای فرم در همین تب میمانند و پس از اعمال در همهٔ پنلها یکسان میشوند.
پیش از شروع مرحلهٔ مسدودکننده، هر سه ترمینال را آماده کنید تا بررسی داخل بازهٔ انتظار جا شود. اگر نام schema موجود بود، متوقف شوید؛ آن را برای راحتی تمرین حذف نکنید.
قدم بعدی
پیش از شروع، مسیر ابزار و محل اجرای فرمانها را بررسی کنید
سرور جداگانهٔ آزمایش باید از قبل MySQL نسخهٔ ۸٫۴ با InnoDB باشد و کلاینت MySQL نیز آماده باشد. Oracle این نسخه را برای Debian نسخههای ۱۲ و ۱۳، Ubuntu نسخهٔ ۲۶٫۰۴ و RHEL و Rocky شاخههای ۹ و ۱۰ فهرست کرده است. Ubuntu نسخهٔ ۲۶٫۱۰ در آن فهرست نیست؛ انتخاب آن فقط کلاینت سازگاری را پوشش میدهد که جداگانه آماده شده و به سرور مجاز متصل میشود. شاخهٔ AlmaLinux نیز مسیر کلاینت سازگار با EL است، نه ادعای تأیید رسمی Oracle. در نصب APT ممکن است بستهٔ mysql-community-client و سرویس mysql.service را ببینید؛ در نصب Yum نام سرویس mysqld.service است. فرمان mysql پیشفرض توزیع یا ماژول پیشفرض دیتابیس را معادل MySQL نسخهٔ ۸٫۴ نگیرید: نسخهٔ کلاینت و سرور را بررسی کنید و اگر محصول دیگری بود ادامه ندهید. فایل محافظتشدهٔ تنظیمات کاربر، در همهٔ شاخهها با مسیر صریح خودش استفاده میشود.
این مسیرها از مستندات استخراج شدهاند و آزمون عملی سازگاری محسوب نمیشوند. ابتدا /etc/os-release و نسخهٔ دقیق محصول را بررسی کنید. حسابها، دسترسی شبکه و اعتبارنامههای محافظتشده باید از قبل آماده باشند. برای آمادهکردن ابزارها، سرویس موجود را دوباره راهاندازی نکنید، دیتابیس تازه مقداردهی اولیه نکنید، پورتی روی فایروال باز نکنید و Python سیستم را تغییر ندهید.
اگر SELinux فعال است، درستبودن مالک و مجوز فایل بهتنهایی کافی نیست. آن را فعال نگه دارید. در صورت ردشدن دسترسی به فایل، سوکت یا اتصال، مسئول مجاز باید رخداد AVC و context واقعی فرایند و فایل را بررسی کند؛ نوع امنیتی را حدس نزنید، chcon بازگشتی اجرا نکنید و policy کلیِ مجازکننده نسازید. بررسی تنظیمات موجود firewalld فقط با مجوز مدیریتی انجام شود؛ این راهنما به قانون ورودی تازه نیاز ندارد.
کلاینت مدیریت مجاز؛ بررسیهای مخصوص گره فقط روی همان گرهٔ موجود
cat /etc/os-release
id
command -v mysql
mysql --version
test -r "/home/academy/.mysql-lab.cnf"
if command -v getenforce >/dev/null; then getenforce; id -Z; fiسیستمعامل، مسیر و نسخهٔ ابزار با محیط انتخابی سازگار است؛ در صورت تفاوت، پیش از تغییر داده توقف کنید.
قدم بعدی
نسخه و امکان مشاهدهٔ قفل را بررسی کنید
اتصال اول را بدون انتخاب دیتابیس باز کنید و نسخه و hostname را ببینید. instrument مربوط به metadata lock باید فعال باشد و نقش شما اجازهٔ مشاهدهٔ اطلاعات لازم را داشته باشد.
اگر sys یا performance_schema در دسترس نیست، از نقش مشاهدهٔ مجازِ همان محیط استفاده کنید. برای ادامهٔ مقاله instrumentation را سراسری تغییر ندهید یا مجوز مدیریتی گسترده نسازید.
کلاینت مدیر مجاز MySQL نسخهٔ ۸٫۴ آزمایشی
mysql --defaults-extra-file='/home/academy/.mysql-lab.cnf' -e "SELECT VERSION(),@@hostname,@@performance_schema; SELECT NAME,ENABLED,TIMED FROM performance_schema.setup_instruments WHERE NAME='wait/lock/metadata/sql/mdl';"سرور MySQL 8.4 است و ابزار لازم برای دیدن انتظار قفل فراداده در دسترس است.
قدم بعدی
جدول آزمایشی سهردیفی بسازید
CREATE DATABASE عمداً بدون IF NOT EXISTS آمده است تا برخورد نام را پنهان نکند. فقط با مجوز مسئول محیط آزمایش اجرا کنید. اگر schema از قبل وجود داشت، متوقف شوید و نام دیگری بررسی کنید.
جدول تازه هیچ دادهٔ مشتری ندارد و فقط سه ردیف نمونه میگیرد. نام دقیق schema را برای بازبینی و پاکسازی بعدی نگه دارید؛ در این مرحله ایندکس ثانویهای ساخته نمیشود.
کلاینت مدیر مجاز MySQL نسخهٔ ۸٫۴ آزمایشی
mysql --defaults-extra-file='/home/academy/.mysql-lab.cnf' <<'SQL'
CREATE DATABASE `academy_mdl_20261028`;
CREATE TABLE `academy_mdl_20261028`.mdl_probe(id INTEGER PRIMARY KEY,category VARCHAR(32) NOT NULL) ENGINE=InnoDB;
INSERT INTO `academy_mdl_20261028`.mdl_probe VALUES(1,'alpha'),(2,'beta'),(3,'alpha');
SELECT * FROM `academy_mdl_20261028`.mdl_probe;
SQLیک schema تازه و جدول سهردیفی InnoDB بدون ایندکس ثانویه ایجاد شدهاند.