«سائٹ سست ہے» تقریباً ہمیشہ ڈیٹابیس تک پہنچتا ہے۔ اور اگر جانچ درست ترتیب سے کی جائے تو چند منٹ لیتی ہے: پہلے وہ جو خود سستی کے دوران نظر آتا ہے، پھر وہ جو ہفتوں سے جمع ہو رہا تھا۔
جب مسئلہ جاری ہو تب دیکھیں
بنیادی اصول: سب سے قیمتی معلومات عین اُسی وقت دستیاب ہوتی ہیں جب سب کچھ سست ہو۔ MySQL کے لیے پہلی کمانڈ:
sudo mysqladmin processlist
mysql -e 'SHOW FULL PROCESSLIST'
PostgreSQL کے لیے:
sudo -u postgres psql -c "SELECT pid, state, wait_event, now()-query_start AS dur, query
FROM pg_stat_activity WHERE state != 'idle' ORDER BY dur DESC;"
آپ دیکھیں گے کہ اِس وقت کیا چل رہا ہے اور کتنی دیر سے۔ اور جواب عموماً فوری ہوتا ہے: کوئی ایک بھاری استفسار باقی سب کو روکے ہوئے ہے، یا سو ایک جیسے استفسار کسی تالے کے کھلنے کے منتظر ہیں۔
کنکشن
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'"
mysql -e "SHOW GLOBAL STATUS LIKE 'Max_used_connections'"
mysql -e "SHOW VARIABLES LIKE 'max_connections'"
اگر Max_used_connections max_connections کے قریب پہنچ رہا ہو تو ایپلیکیشن وقتاً فوقتاً «too many connections» کا انکار پا رہی ہے۔ اور حد بڑھانا پہلا کام نہیں ہونا چاہیے: ہر کنکشن میموری لیتا ہے، اور جس سرور میں میموری پہلے ہی کم ہو وہاں اسے بڑھانا صرف سویپ تک کے سفر کو تیز کرتا ہے۔ پہلے یہ معلوم کریں کہ کنکشن آزاد کیوں نہیں ہو رہے: عموماً کوئی لمبا استفسار یا ایپلیکیشن کی طرف کنکشن پول کی عدم موجودگی۔
اور اسے دوسری طرف سے بھی دیکھنا چاہیے: کنکشن میں تیز اضافہ بڑھتی مقبولیت سے نہیں بلکہ کسی بھاری صفحے کو پیٹنے والے بوٹوں سے بھی آ سکتا ہے — کوئی تلاش، فہرست کا فلٹر، رپورٹ بنانے والا۔
سست استفسار
سست استفسار کے لاگ کے بغیر آگے جانے کی کوئی جگہ نہیں۔ MySQL:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
ایک دن بعد:
sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
PostgreSQL، postgresql.conf میں:
log_min_duration_statement = 1000
پھر توسیع pg_stat_statements، جو فی استفسار کل وقت براہِ راست دکھاتی ہے:
SELECT calls, round(total_exec_time) AS total_ms, query
FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;
دھیان رہے: اہم سب سے لمبا استفسار نہیں بلکہ وہ ہے جس کا کل وقت سب سے زیادہ ہو۔ 50 ملی سیکنڈ کا استفسار جو منٹ میں ہزار بار چلے، دن میں ایک بار چلنے والی دس سیکنڈ کی رپورٹ سے زیادہ نقصان کرتا ہے۔
وہ ترتیب جو سب سے زیادہ بھلائی جاتی ہے
MySQL اور MariaDB کے لیے یہ InnoDB کے بفر پول کا حجم ہے۔ طے شدہ قدر 128 میگابائٹ ہے اور دہائیوں سے نہیں بدلی۔ اور ایسے سرور پر جہاں ڈیٹابیس کئی گیگابائٹ گھیرتا ہو، اس کا مطلب میموری کے بجائے ڈسک سے مسلسل پڑھنا ہے۔
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'"
مخصوص ڈیٹابیس سرور کے لیے معقول پیمانہ RAM کا نصف ہے؛ اور ایسے سرور کے لیے جس پر ویب سرور اور PHP بھی چل رہے ہوں، ایک چوتھائی، اس خیال کے ساتھ کہ سویپ میں نہ جائے۔ اور یہ ایک ترتیب عموماً ایک ہفتے کی استفسار کی بہتری سے زیادہ دیتی ہے۔
دو چیزیں جو خاموشی سے ڈسک کھا جاتی ہیں
MySQL کے بائنری لاگ۔ یہ نقل سازی اور وقت کے کسی نقطے تک بحالی کے لیے درکار ہیں، مسلسل بڑھتے ہیں، اور بطور طے شدہ کبھی کبھی کبھی نہیں مٹتے۔ جانچ کے لیے:
sudo du -sh /var/lib/mysql/*bin.*
mysql -e "SHOW VARIABLES LIKE 'binlog_expire_logs_seconds'"
اگر آپ کے ہاں نقل سازی نہیں اور آپ وقت کے نقطے تک بحالی استعمال نہیں کرتے تو محفوظ رکھنے کی مدت چند معقول دن رکھ دیں۔
PostgreSQL کی WAL فائلیں بھلائے گئے نقل سازی سلاٹ کے ساتھ۔ کم معروف اور زیادہ خطرناک صورت: اگر نقل سازی کا سلاٹ موجود ہو مگر اس کا صارف اب نہ جڑ رہا ہو تو PostgreSQL منقطع ہونے کے لمحے سے ہر لاگ محفوظ رکھنے کا پابند ہے — اور ڈسک ختم ہونے تک رکھے گا۔
sudo -u postgres psql -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"
ایسا غیر فعال سلاٹ جس کی کسی کو ضرورت نہیں، مٹا دینا چاہیے۔ اور یہ ان چند صورتوں میں سے ایک ہے جہاں ڈیٹابیس یقینی طور پر ڈسک کو صفر تک لے آتا ہے۔
حجم اور اضافہ
SELECT table_schema, round(sum(data_length+index_length)/1024/1024) AS mb
FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC;
اور مفید موجودہ عدد نہیں بلکہ اس کی تبدیلی کی رفتار ہے۔ ایسا ڈیٹابیس جو ٹریفک میں متناسب اضافے کے بغیر ایک مہینے میں دگنا ہو گیا ہو، عموماً اس کا مطلب ہے کہ کوئی اندراج کی جدول لکھی جا رہی ہے اور کبھی صاف نہیں ہوتی — سیشن، کاموں کی تاریخ، کسی پلگ اِن کے واقعات کا لاگ۔
دو سطروں میں سلامتی
اور جب ڈیٹابیس کا کنسول کھلا ہی ہے تو دو چیزیں جانچ لینے کے قابل ہیں۔ پہلی، کیا ڈیٹابیس باہر سے قابلِ رسائی ہے (ss -tulpn | grep 3306): اسے تقریباً کبھی باہر نہیں دیکھنا چاہیے۔ اور دوسری، وہ اکاؤنٹ جو کسی بھی پتے سے جڑ سکتے ہیں:
mysql -e "SELECT user, host FROM mysql.user"
host = '%' والے اندراج کا مطلب ہے «ہر جگہ سے کنکشن»۔ اور اگر پورٹ بھی کھلا ہو تو ڈیٹابیس اور انٹرنیٹ کے درمیان صرف ایک پاس ورڈ کھڑا ہے۔
بیک اپ
آخری بات۔ بیک اپ فائل کا وجود کچھ ضمانت نہیں دیتا؛ ضمانت صرف آزمائی گئی بحالی دیتی ہے۔ ایسی نقل جو کبھی بحال نہ کی گئی ہو، برابر امکان رکھتی ہے کہ کٹی ہوئی نکلے، تالے کی خرابی کے ساتھ لی گئی ہو، یا اس میں غلط ڈیٹابیس ہو۔ اور یہ پہلے سے اور کسی الگ مشین پر جانچنا چاہیے، نہ کہ اُس دن جب نقل کی ضرورت پڑے۔
روزمرہ نگرانی کے لیے تین اعداد کافی ہیں: کنکشن کی تعداد، روزانہ سست استفسار کی تعداد، اور ڈیٹابیس کا حجم۔ تینوں آہستہ اور قابلِ پیش گوئی انداز میں بدلتے ہیں، اور ان میں سے کسی ایک کی تیز حرکت نظر ڈالنے کے قابل ہے۔ یہ ایک صفحے پر کیسے لگتے ہیں، نیچے ڈیمو دکھاتا ہے۔