طبق گفته سازندههاش، پستگرسکیوال یک سیستم مدیریت پایگاه داده شیگرا-رابطهای و متنبازه. میدونم، میدونم، این جمله خودش کلی کلمه قلمبه سلمبه داره. بیاین تیکهتیکهش کنیم:
- پایگاه داده (Database): فکر کنین یه دفترچه یادداشت خیلی خیلی بزرگ و هوشمند دارین که میتونین اطلاعات رو خیلی مرتب و منظم توش ذخیره کنین. مثلا اطلاعات دانشجوهای یه دانشگاه، محصولات یه فروشگاه آنلاین، یا لیست آهنگهای یه اپلیکیشن موسیقی. به این دفترچه هوشمند میگن پایگاه داده. کارش اینه که اطلاعات رو نگه داره، بهمون اجازه بده توش جستجو کنیم، اطلاعات جدید اضافه کنیم یا اطلاعات قبلی رو تغییر بدیم.
- سیستم مدیریت پایگاه داده (Database System): حالا اون نرمافزاری که به ما اجازه میده اون دفترچه هوشمند (پایگاه داده) رو بسازیم و مدیریتش کنیم، میشه سیستم مدیریت پایگاه داده. پستگرسکیوال دقیقا همین کار رو میکنه. یه جورایی مثل اون برنامه دفترچه یادداشت توی کامپیوتر یا گوشیتونه، ولی هزاران بار قویتر و پیشرفتهتر.
- رابطهای (Relational): این کلمه یعنی اطلاعات توی جدولهای مختلفی ذخیره میشن که به هم ربط دارن. مثلا یه جدول داریم برای دانشجوها، یه جدول دیگه برای درسها. بعد میتونیم بین این دوتا جدول یه رابطه برقرار کنیم تا مشخص بشه هر دانشجویی چه درسهایی رو برداشته. اینجوری همه چیز خیلی منظم و دستهبندی شده باقی میمونه.
- شیگرا (Object-Relational): این یه ویژگی پیشرفتهتره. یعنی پستگرسکیوال فقط به مدل رابطهای محدود نیست و میتونه ساختارهای داده پیچیدهتری رو هم مدیریت کنه. فعلا خیلی درگیر این قسمتش نشین، همینقدر بدونین که این ویژگی دستش رو برای کارهای پیچیدهتر باز میذاره.
- متنباز (Open Source): این یعنی کد اصلی برنامه پستگرسکیوال در دسترس همه هست. هر کسی میتونه اون رو ببینه، تغییر بده و حتی در بهتر شدنش کمک کنه. این باعث میشه یه جامعه بزرگ از متخصصها در سراسر دنیا روی توسعهش کار کنن و همیشه در حال پیشرفت باشه.
این سیستم بیشتر از ۳۵ ساله که داره به صورت فعال توسعه داده میشه. این زمان طولانی باعث شده که به عنوان یه ابزار خیلی قابل اعتماد، پر از امکانات و با عملکرد خوب شناخته بشه. به خاطر همین متنباز بودنش، کلی اطلاعات و راهنمای رسمی برای نصب و استفاده ازش وجود داره. جامعه کاربری خیلی بزرگی هم داره که همیشه آماده کمک کردن هستن و میتونین از طریق اونها با طرز کارش آشنا بشین یا حتی فرصتهای شغلی پیدا کنین.
بخش دوم: سرور، کلاینت، اسکیوال؛ مفاهیم پایه رو یاد بگیریم
وقتی برای اولین بار با ابزارهایی مثل پستگرسکیوال کار میکنین، یه سری کلمهها مثل «سرور» مدام به چشمتون میخوره. یکی از کاربرها توی ردیت دقیقا همین سوال رو پرسیده بود که «این سرورهایی که توی pgAdmin (یه ابزار برای مدیریت پستگرس) میبینیم چی هستن؟» این سوال خیلی خوبیه، چون به قلب ماجرا میزنه.
سرور چیه و چه ربطی به پایگاه داده داره؟
بیایم با تعریف اصلی شروع کنیم.
یک سرور (Server) میتونه یه قطعه سختافزاری باشه (مثلا یه کامپیوتر خیلی قوی) یا یه نرمافزار که به بقیه برنامهها یا دستگاهها سرویس میده. به اون برنامههایی که سرویس میگیرن میگن کلاینت (Client).
حالا، سرور پایگاه داده (Database Server) یه سروره که یه برنامه پایگاه داده (مثل پستگرسکیوال) روش نصبه و داره سرویسهای مربوط به پایگاه داده رو به بقیه برنامهها ارائه میده.
تصور کنین شما یه اپلیکیشن روی گوشیتون دارین (مثلا اینستاگرام). این اپلیکیشن کلاینته. وقتی شما میخواین عکسهای جدید رو ببینین، اپلیکیشن شما یه درخواست به سرورهای اینستاگرام میفرسته. روی اون سرورها، یه سرور پایگاه داده نصبه که اطلاعات عکسها، کامنتها و لایکها رو نگه میداره. سرور پایگاه داده اطلاعات رو پیدا میکنه و برای اپلیکیشن شما میفرسته.
پس وقتی توی ابزاری مثل pgAdmin یه چیزی به اسم «Servers» میبینین، منظور همون اتصال به یک سرور پایگاه داده هست. شما میتونین از کامپیوتر خودتون به چندین سرور پایگاه داده مختلف وصل بشین. مثلا یکی ممکنه روی کامپیوتر خودتون نصب باشه برای تمرین (که بهش میگن سرور محلی یا Local Server) و یکی دیگه ممکنه یه کامپیوتر اون سر دنیا باشه که اطلاعات واقعی یه سایت روشه (سرور راه دور یا Remote Server).
گاهی هم ممکنه ببینین کنار اسم سرور یه عدد نوشته شده، مثلا «PostgreSQL 13». این عدد معمولا به نسخه اون نرمافزار پستگرسکیوال که روی سرور نصبه اشاره داره.
پستگرسکیوال زبانه یا سرور؟ قصه SQL چیه؟
اینم یه سوال خیلی رایجه. خیلیا گیج میشن که فرق بین SQL و PostgreSQL چیه.
بذارین اینطوری بگم:
- SQL (Structured Query Language): این اسم یک زبانه. یه زبان استاندارد برای حرف زدن با پایگاه دادههای رابطهای. شما با استفاده از دستورهای این زبان، از پایگاه داده میخواین که یه کاری براتون انجام بده. مثلا «این اطلاعات رو بهم نشون بده» یا «این کاربر جدید رو اضافه کن».
- PostgreSQL: این اسم یک نرمافزاره. یک سیستم مدیریت پایگاه داده. این نرمافزار زبان SQL رو میفهمه. شما دستورهای SQL رو بهش میدین و اون براتون اجراشون میکنه.
پس پستگرسکیوال هم یک سروره (نرمافزاری که سرویس میده) و هم میشه گفت یه جورایی یه «زبانه» چون نسخه مخصوص به خودش از SQL رو پیادهسازی کرده.
یه نکته جالب اینه که شرکتهای مختلف، نرمافزارهای پایگاه داده خودشون رو ساختن. مثلا:
- Oracle
- MySQL (که الان مال اوراکله)
- MariaDB
- Microsoft SQL Server
- و البته PostgreSQL
همه اینها زبان استاندارد SQL رو به عنوان پایه قبول دارن، ولی هر کدوم یه سری دستورها و ویژگیهای مخصوص به خودشون رو هم اضافه کردن. مثل لهجههای مختلف یه زبان میمونه. هسته اصلی یکیه، ولی تو جزئیات تفاوت دارن. اگه بخوایم با نمودار ون تصور کنیم، یه دایره بزرگ هست به اسم SQL که دستورهای اصلی توشه، و بعد دایرههای کوچیکتری برای هر کدوم از این نرمافزارها (PostgreSQL, MySQL, …) وجود داره که بخش زیادیشون با هم همپوشانی داره.
یه نکته دیگه هم اینکه حواستون باشه اسم «SQL Server» که مال مایکروسافته رو با مفهوم کلی «سرور SQL» اشتباه نگیرین. اولی اسم یه محصول خاصه، دومی یه مفهوم کلی.
دو نوع دستور مهم در SQL
وقتی با کد SQL سر و کار دارین، خوبه که بدونین دستورهاش معمولا به دو دسته اصلی تقسیم میشن:
- DML (Data Manipulation Language): زبان دستکاری دادهها. این دستورها کارشون با خود دادههاست. یعنی دادهها رو «تغییر» میدن. مثلا:
INSERT
: یه ردیف داده جدید اضافه میکنه.UPDATE
: دادههای موجود رو بهروز میکنه.DELETE
: دادهها رو حذف میکنه.
- DDL (Data Definition Language): زبان تعریف دادهها. این دستورها با ساختار پایگاه داده کار دارن. یعنی اون جدولها و روابط بینشون رو «تعریف» یا «تغیبر» میدن. مثلا:
CREATE TABLE
: یه جدول جدید میسازه.ALTER TABLE
: ساختار یه جدول موجود رو تغییر میده.DROP TABLE
: یه جدول رو کلا حذف میکنه.
درک این تفاوت بهتون کمک میکنه که بهتر بفهمین هر دستور داره چیکار میکنه.
بخش سوم: چطوری پستگرسکیوال رو نصب و راهاندازی کنیم؟
خب، حالا که با مفاهیم اولیه آشنا شدیم، ببینیم چطوری میشه این نرمافزار رو روی کامپیوترمون داشته باشیم. راههای مختلفی برای این کار وجود داره.
راههای مختلف برای دریافت پستگرسکیوال
شما میتونین پستگرسکیوال رو به چند شکل مختلف دانلود کنین:
- بستههای آماده (Ready-to-use packages) یا نصبکنندهها (Installers): این سادهترین راهه. برای سیستمعاملهای مختلف مثل ویندوز، مک و توزیعهای مختلف لینوکس، فایلهای نصب آمادهای وجود داره که شما فقط دانلود و اجراشون میکنین و مراحل رو دنبال میکنین.
- سورس کد (Source code archive): اگه خیلی حرفهای هستین و دوست دارین خودتون نرمافزار رو از پایه بسازین (کامپایل کنین)، میتونین سورس کدش رو دانلود کنین. دستورالعملهای ساختنش هم توی راهنمای رسمیش هست. مخزن سورس کدش هم روی
git.postgresql.org
قرار داره. - نسخههای آزمایشی (Beta and release candidates): اگه دوست دارین ویژگیهای جدیدی که هنوز به طور رسمی منتشر نشدن رو تست کنین، میتونین نسخههای بتا یا کاندیدای انتشار رو دانلود کنین. خیلی مهمه که بدونین این نسخهها فقط برای تست هستن و نباید روی سیستمهای واقعی و کاری ازشون استفاده کنین.
پشتههای نرمافزاری آماده
گاهی اوقات شما برای راهاندازی یه وبسایت یا برنامه، فقط به پایگاه داده نیاز ندارین. به یه وب سرور (مثل آپاچی) و یه زبان برنامهنویسی (مثل PHP) هم احتیاج دارین. به مجموعه این نرمافزارها که با هم کار میکنن میگن «پشته» یا Stack.
شرکتی به اسم BitNami پشتههای آمادهای رو درست کرده که کار رو خیلی راحت میکنه. این پشتهها شامل این موارد هستن:
- LAPP: لینوکس + آپاچی + پیاچپی + پستگرسکیوال
- MAPP: مک + آپاچی + پیاچپی + پستگرسکیوال
- WAPP: ویندوز + آپاچی + پیاچپی + پستگرسکیوال
با نصب این پشتهها، همه ابزارهای لازم برای شروع کار به صورت یکجا و هماهنگ با هم نصب میشن.
نرمافزارهای جانبی و کاتالوگ
دنیای پستگرسکیوال خیلی بزرگه و کلی نرمافزار دیگه هم وجود داره که باهاش کار میکنن ولی به صورت پیشفرض همراهش نیستن. توی سایت رسمی پستگرسکیوال یه بخشی به اسم «کاتالوگ نرمافزار» (Software Catalogue) وجود داره که لیست بزرگی از برنامههای تجاری و متنباز، رابطها و افزونههای مختلف رو میتونین توش پیدا کنین. اگه خودتون هم محصولی ساختین که با پستگرسکیوال کار میکنه، میتونین با پر کردن یه فرم، اون رو به این کاتالوگ اضافه کنین.
یک راه ساده برای تمرین: Docker
اگه تازه دارین یاد میگیرین، شاید نخواین کلی نرمافزار روی سیستمعامل اصلیتون نصب کنین. اینجا ابزاری به اسم داکر (Docker) خیلی به درد میخوره. داکر به شما اجازه میده برنامهها رو توی محیطهای ایزولهای به اسم «کانتینر» اجرا کنین. اینجوری میتونین یه پایگاه داده پستگرسکیوال رو خیلی سریع راه بندازین، باهاش تمرین کنین و بعد با یه دستور ساده همه چیز رو پاک کنین، بدون اینکه کامپیوترتون شلوغ بشه.
مثلا با دستور زیر میشه یه کانتینر پستگرس نسخه ۱۳.۳ رو راه انداخت:
docker run --rm -p 5432:5432 --name some-postgres-container-name -e POSTGRES_PASSWORD=mysecretpassword postgres:13.3
بیاین این دستور رو با هم بررسی کنیم:
docker run
: به داکر میگه یه کانتینر جدید رو اجرا کن.--rm
: میگه وقتی کارم با کانتینر تموم شد و متوقفش کردم، خودکار حذفش کن. این برای تمرین عالیه.-p 5432:5432
: این بخش مربوط به پورتهاست. میگه پورت5432
کامپیوتر من رو به پورت5432
داخل کانتینر وصل کن. پورت5432
پورت استاندارد پستگرسکیواله.--name some-postgres-container-name
: یه اسم برای کانتینرمون انتخاب میکنیم.-e POSTGRES_PASSWORD=mysecretpassword
: یه متغیر محیطی به اسمPOSTGRES_PASSWORD
رو تنظیم میکنه و مقدارش رو برابر باmysecretpassword
قرار میده. این پسورد کاربر اصلی پایگاه داده میشه.postgres:13.3
: اسم و نسخه ایمیجی که میخوایم از روش کانتینر رو بسازیم. اینجا یعنی ایمیج رسمی پستگرس با نسخه13.3
.
یه نکته مهم اینه که همیشه سعی کنین نسخه مشخصی از ایمیج رو استفاده کنین (مثلا 13.3
) و از latest
استفاده نکنین، چون ممکنه در آینده آپدیت بشه و رفتارش تغییر کنه.
بخش چهارم: وقتی اوضاع خراب میشه؛ آموزش عیبیابی (Troubleshooting)
هیچ سیستمی همیشه بینقص کار نمیکنه. گاهی وقتا به مشکل میخوریم. مهم اینه که بدونیم چطوری مشکل رو پیدا و حل کنیم. تو این بخش میخوایم دو تا سناریوی واقعی از مشکلاتی که برای کاربرا پیش اومده رو با هم بررسی کنیم و ببینیم چطوری میشه مثل یه کارآگاه، رد خطاها رو گرفت و به جواب رسید.
سناریو اول: «بعد از آپدیت، سیستم بالا نمیاد و میگه سرور پستگرس استارت نشد!»
این مشکل برای یه کاربر سیستمعامل مانجارو لینوکس پیش اومده بود. کامپیوترش که برای کار ازش استفاده میکرد، بعد از یه آپدیت دیگه بالا نمیومد و روی لوگوی ASRock (مارک مادربوردش) گیر میکرد. پیام خطای اصلی این بود: Failed to start PostgreSQL database server
(سرور پایگاه داده پستگرسکیوال شروع به کار نکرد).
اینجا کاربر با کمک بقیه، شروع به تحقیق میکنه. اولین قدم اینه که ببینیم سیستم دقیقا داره چه خطاهایی میده. برای این کار از یه دستور به اسم journalctl
استفاده میشه. این دستور، گزارشها و رویدادهای سیستم (که بهشون میگن log) رو نشون میده.
دستوری که استفاده شد این بود: journalctl -xep 0..3
journalctl
: خود برنامه.-x
: اطلاعات بیشتری در مورد هر خطا میده.-e
: مستقیم میره به آخر گزارشها که جدیدترین خطاها اونجا هستن.-p 0..3
: میگه فقط پیامهایی با اولویت بالا رو نشون بده (از ۰ تا ۳ که شامل Emergency, Alert, Critical, Error میشه).
حالا بیاین با هم لاگهایی که این دستور نشون داده رو بررسی کنیم. این لاگها خیلی طولانی و ترسناک به نظر میرسن، ولی اگه با دقت و حوصله بخونیمشون، سرنخهای خوبی بهمون میدن.
کالبدشکافی لاگهای سیستم
من بخشهای مهم و تکراری لاگ رو براتون جدا کردم تا تحلیلشون کنیم.
سرنخ اول: مشکلات مربوط به Firmware و Microcode
Jun 01 12:43:27 user-pc kernel: [Firmware Bug]: TSC_DEADLINE disabled due to Errata; please update microcode to version: 0x3a (or later)
kernel
: هسته اصلی سیستمعامل. این پیام از پایینترین سطح نرمافزاری سیستم میاد.Firmware Bug
: یعنی یه باگ توی سفتافزار (نرمافزار سطح پایینی که روی سختافزارها مثل CPU یا مادربورد اجرا میشه) وجود داره.please update microcode
: سیستم داره پیشنهاد میده که میکروکد سیپییو رو آپدیت کنیم. میکروکد یه جورایی مثل یه آپدیت برای خود سیپییو هست که بعضی از باگهاش رو برطرف میکنه.
نتیجهگیری اولیه:
همین اول کار، سیستم داره بهمون میگه که یه مشکل سطح پایین سختافزاری/نرمافزاری وجود داره. این خودش یه زنگ خطره.
سرنخ دوم: پیدا نشدن ماژولهای کرنل
این خطا بارها و بارها توی لاگها تکرار شده:
Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxdrv'
Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxnetadp'
Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxnetflt'
Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'nvidia'
Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'nvidia-drm'
Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'zfs'
systemd-modules-load
: یه بخشی از سیستمعامل که مسئول بارگذاری ماژولهای کرنله.- ماژول کرنل چیه؟ فکر کنین کرنل سیستمعامل مثل یه موتور ماشینه. ماژولها مثل قطعات اضافی هستن که به این موتور وصل میشن تا کارهای خاصی رو انجام بدن. مثلا درایور کارت گرافیک، درایور کارت شبکه و… .
Failed to find module
: یعنی سیستم نتونسته این ماژولها رو پیدا و بارگذاری کنه.vboxdrv
,vboxnetadp
,vboxnetflt
: اینها مربوط به نرمافزار VirtualBox هستن که برای ساخت ماشینهای مجازی استفاده میشه.nvidia
,nvidia-drm
: اینها مربوط به درایور کارت گرافیک Nvidia هستن.zfs
: این مربوط به یه نوع سیستم فایل پیشرفته به اسم ZFS هست.
نتیجهگیری دوم:
به نظر میاد بعد از اون آپدیت، درایورهای مهمی مثل درایور کارت گرافیک و ابزارهای مجازیسازی به درستی نصب نشدن یا با نسخه جدید کرنل سازگار نیستن. این میتونه باعث بیثباتی کل سیستم بشه.
سرنخ سوم: خطاهای مربوط به حافظه و سختافزار
این خطا هم خیلی زیاد تکرار شده:
Jun 01 12:43:44 user-pc kernel: EDAC sbridge: CPU SrcID #0, Ha #0, Channel #0 has DIMMs, but ECC is disabled
Jun 01 12:43:44 user-pc kernel: EDAC sbridge: Couldn't find mci handler
Jun 01 12:43:44 user-pc kernel: EDAC sbridge: Failed to register device with error -19.
EDAC (Error Detection and Correction)
: یه قابلیتی توی سختافزارها برای پیدا کردن و تصحیح خطاهای حافظه.ECC is disabled
: یعنی حافظه ECC (که نوع خاصی از رم برای سرورهاست و قابلیت تصحیح خطا داره) غیرفعاله. این ممکنه برای یه کامپیوتر شخصی عادی باشه، ولی خود پیام خطا نشون میده که سیستم در حال بررسی عمیق سختافزاره.Failed to register device with error -19
: این پیام خیلی کلیه ولی نشون میده که کرنل نتونسته یه قطعه سختافزاری رو به درستی شناسایی و راهاندازی کنه.
نتیجهگیری سوم:
علاوه بر مشکلات درایور، به نظر میاد سیستم در ارتباط با بعضی از قطعات سختافزاری هم مشکل داره.
سرنخ چهارم: خطای نهایی پستگرس
و بالاخره میرسیم به خطایی که کاربر از اول دیده بود:
Jun 01 12:43:46 user-pc systemd[1]: Failed to start PostgreSQL database server.این پیام توسط systemd
صادر شده که مدیر سیستم و سرویسها در لینوکسه. این پیام به ما نمیگه چرا پستگرس استارت نشده، فقط میگه که تلاشش برای این کار ناموفق بوده.
جمعبندی کارآگاهی سناریو اول:
مشکل اصلی به احتمال زیاد خود پستگرسکیوال نیست. مشکل اینه که کل سیستمعامل بعد از آپدیت به هم ریخته و بیثبات شده. وقتی درایورهای اصلی مثل درایور گرافیک بارگذاری نمیشن و کرنل در شناسایی سختافزارها مشکل داره، سیستم نمیتونه یه محیط پایدار برای اجرای سرویسهای دیگه مثل پستگرسکیوال فراهم کنه. راهحل در این مورد، احتمالا تعمیر سیستمعامل، نصب مجدد درایورها، یا برگردوندن آپدیتهاست، نه دستکاری کردن تنظیمات خود پستگرس. این یه درس مهمه: گاهی اوقات ریشه مشکل جاییه که اصلا انتظارش رو نداریم.
سناریو دوم: «نمیتونم به سرور وصل بشم، میگه همچین فایلی وجود نداره!»
این یکی مشکل رایجتریه و معمولا مستقیم به خود پستگرس ربط داره. یه کاربر روی اوبونتو ۱۸.۰۴ با این خطا مواجه شده:
psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket “/var/run/postgresql/.s.PGSQL.5432”?این خطا یعنی برنامه psql
(که ابزار خط فرمان برای وصل شدن به پستگرسه) نتونسته به سرور پستگرس وصل بشه. داره میپرسه که آیا سرور به صورت محلی (locally) روشنه و روی یه چیزی به اسم «سوکت دامنه یونیکس» داره گوش میده یا نه.
بیاین مراحل عیبیابی این کاربر رو دنبال کنیم:
قدم اول: وضعیت سرویس رو چک کنیم
اولین کاری که باید بکنیم اینه که ببینیم آیا سرویس پستگرسکیوال اصلا روشنه یا نه.
sudo systemctl status postgresql
کاربر این دستور رو زده و دیده که سیستم میگه سرویس «فعاله». حتی با دستور restart
هم سرویس رو دوباره راهاندازی کرده ولی مشکل حل نشده. این یکم عجیبه.
قدم دوم: لیست کلاسترهای پستگرس رو ببینیم
در سیستمعاملهای مبتنی بر دبیان (مثل اوبونتو)، پستگرس با مفهومی به اسم «کلاستر» کار میکنه. هر کلاستر یه نمونه جدا از سرور پستگرسه که میتونه تنظیمات، پورت و مسیر دادههای خودشو داشته باشه. با دستور زیر میشه لیست کلاسترها رو دید:
pg_lsclusters
وقتی کاربر این دستور رو میزنه، با این خروجی مواجه میشه:
Ver Cluster Port Status Owner Data directory Log file
10 main 5432 down postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
11 main 5433 down postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
12 main 5434 down postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
این خروجی خیلی مهمه! ستون Status
(وضعیت) برای همه کلاسترها down (خاموش) رو نشون میده. پس بر خلاف چیزی که systemctl
میگفت، سرورهای پستگرس در واقع خاموش هستن!
قدم سوم: تلاش برای روشن کردن دستی کلاستر
حالا کاربر سعی میکنه یکی از کلاسترها رو دستی روشن کنه:
sudo pg_ctlcluster 10 main start
اما این دستور هم خطا میده و میگه سرویس نتونسته استارت بشه و برای جزئیات بیشتر لاگها رو چک کنین.
قدم چهارم: خوندن فایل لاگ پستگرس
این مهمترین مرحلهست. ما باید بریم سراغ فایل لاگی که خود پستگرسکیوال مینویسه تا ببینیم دردش چیه. مسیر فایل لاگ توی خروجی pg_lsclusters
مشخص شده بود.
sudo nano /var/log/postgresql/postgresql-10-main.log
(nano
یه ویرایشگر متن ساده در خط فرمانه)
و بالاخره، سرنخ اصلی پیدا میشه. داخل فایل لاگ این خطا نوشته شده:
2020-09-29 02:27:06.445 WAT [25041] FATAL: data directory "/var/lib/postgresql/10/main" has group or world access
2020-09-29 02:27:06.445 WAT [25041] DETAIL: Permissions should be u=rwx (0700).
FATAL
: یعنی یه خطای خیلی جدی که جلوی اجرای برنامه رو گرفته.data directory ... has group or world access
: میگه پوشهای که دادههای پستگرس توش ذخیره میشه (/var/lib/postgresql/10/main
)، دسترسیهای بیش از حدی داره. یعنی بقیه کاربرهای سیستم (group یا world) هم میتونن بهش دسترسی داشته باشن.Permissions should be u=rwx (0700)
: خود پستگرس داره راهحل رو هم میگه. میگه سطح دسترسی (Permission) این پوشه باید0700
باشه.
سطح دسترسی یا Permission چیه؟
در سیستمعاملهای لینوکسی، برای هر فایل و پوشه مشخص میشه که چه کسانی چه کارهایی میتونن روش انجام بدن. این افراد به سه دسته تقسیم میشن:
- User (u): مالک فایل.
- Group (g): گروهی که مالک فایل عضو اون هست.
- Others/World (o): بقیه کاربران سیستم.
کارها هم سه نوع هستن:
- Read (r): خوندن
- Write (w): نوشتن
- Execute (x): اجرا کردن
سطح دسترسی 0700
یعنی:
- User: دسترسی کامل برای خوندن، نوشتن و اجرا کردن داره (
rwx
). - Group: هیچ دسترسیای نداره.
- Others: هیچ دسترسیای نداره.
چرا پستگرس اینقدر حساسه؟
چون دادههای داخل پایگاه داده خیلی مهمن. اگه هر کاربری توی سیستم بتونه فایلهای داده رو بخونه یا تغییر بده، یه فاجعه امنیتی رخ میده. برای همین پستگرس قبل از اینکه روشن بشه، چک میکنه و اگه ببینه پوشه دادههاش امن نیست، اصلا روشن نمیشه.
قدم پنجم: تصحیح سطح دسترسی و راهاندازی مجدد
حالا که مشکل پیدا شد، راهحلش سادهست. باید سطح دسترسی پوشهها رو درست کنیم.
sudo chmod -R 0700 /var/lib/postgresql/10/main
sudo chmod -R 0700 /var/lib/postgresql/11/main
sudo chmod -R 0700 /var/lib/postgresql/12/main
chmod
: دستوری برای تغییر سطح دسترسی.-R
: یعنی این تغییر رو روی خود پوشه و تمام فایلها و پوشههای داخلش هم اعمال کن (Recursive).
بعد از اجرای این دستورها، کاربر دوباره سعی میکنه کلاسترها رو روشن کنه:
sudo pg_ctlcluster 10 main start
sudo pg_ctlcluster 11 main start
sudo pg_ctlcluster 12 main start
و این بار موفقیتآمیز بود. در نهایت با چک کردن دوباره وضعیت کلاسترها، میبینه که همه online
شدن:
Ver Cluster Port Status Owner Data directory Log file
10 main 5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
11 main 5433 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
12 main 5434 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
و مشکل حل میشه.
سناریو سوم: خطای «authentication failed» با داکر
یه مشکل رایج دیگه وقتی پیش میاد که شما هم روی کامپیوتر خودتون (مثلا ویندوز ۱۱) پستگرس رو نصب کردین، و هم دارین سعی میکنین یه نسخه دیگه از پستگرس رو با داکر اجرا کنین.
مشکل اینه: هر دوتاشون به صورت پیشفرض سعی میکنن از پورت 5432
استفاده کنن.
پورت شبکه چیه؟
فکر کنین آدرس آیپی کامپیوتر شما مثل آدرس یه ساختمون بزرگه. پورتها مثل شماره واحدهای توی اون ساختمون هستن. وقتی یه برنامه میخواد با یه برنامه دیگه روی شبکه حرف بزنه، باید هم آدرس ساختمون (IP) و هم شماره واحد (Port) رو بدونه.
وقتی شما دو تا سرور پستگرس رو همزمان روشن میکنین که هر دو میخوان از پورت 5432
استفاده کنن، مثل این میمونه که دو نفر بخوان توی یه آپارتمان با شماره واحد یکسان زندگی کنن. سیستم قاطی میکنه و نمیدونه درخواستها رو باید به کدوم یکی بفرسته.
علامت مشکل چیه؟
معمولا خطایی مثل p1000 authentication failed
میگیرین. دلیلش اینه که ابزار شما (مثلا Prisma که یه ابزار برای کار با پایگاه دادهست) داره سعی میکنه با اطلاعات کاربری پستگرسِ داخل داکر، به پستگرسِ نصب شده روی کامپیوتر اصلیتون وصل بشه (چون اون پورت 5432
رو اشغال کرده). طبیعتا اطلاعات کاربری با هم نمیخونه و خطا میده.
راهحل چیه؟
راهحل سادهست: باید شماره پورت یکی از اونها رو عوض کنیم. توی سناریوی داکر، این کار خیلی راحته. فقط کافیه موقع اجرای کانتینر، نگاشت پورت رو تغییر بدیم.
دستور قبلی این بود:
docker run ... -p 5432:5432 ...
دستور جدید این میشه:
docker run ... -p 5433:5432 ...
این تغییر یعنی چی؟
-p 5433:5432
: به داکر میگه «هر درخواستی به پورت5433
کامپیوتر من اومد، اون رو بفرست به پورت5432
داخل کانتینر».
اینجوری، پستگرس نصب شده روی سیستم اصلی شما روی پورت 5432
کار میکنه و پستگرس داخل داکر روی پورت 5433
. دیگه با هم تداخلی ندارن و شما میتونین با مشخص کردن پورت درست، به هر کدوم که خواستین وصل بشین.
بخش پنجم: مدیریت روزمره پایگاه داده
خب، حالا که سرورمون راه افتاده و مشکلات احتمالی رو هم بلدیم حل کنیم، بیاین یه نگاهی به کارهای روزمره بندازیم.
پایگاه دادههای پیشفرض: postgres
, template1
, template0
وقتی پستگرسکیوال برای اولین بار نصب میشه، چند تا پایگاه داده رو به صورت خودکار میسازه. شاید از خودتون بپرسین اینها به چه دردی میخورن.
postgres
: این پایگاه داده به عنوان نقطه اتصال پیشفرض برای ابزارها و کاربرها ساخته شده. وقتی شما برنامهای مثلpsql
رو باز میکنین و مشخص نمیکنین به کدوم پایگاه داده میخواین وصل بشین، به صورت خودکار بهpostgres
وصل میشه. یه جورایی مثل لابی یه هتله. شما اول وارد لابی میشین، بعد تصمیم میگیرین به کدوم اتاق برین. خود سرور پستگرس برای کار کردنش به این پایگاه داده نیازی نداره، ولی خیلی از ابزارهای جانبی فرض میکنن که این پایگاه داده وجود داره. پس بهتره حذفش نکنین.template1
: این یکی خیلی جالبه. اسمش یعنی «قالب شماره ۱». هر وقت شما یه پایگاه داده جدید میسازین، پستگرس در واقع یه کپی کامل ازtemplate1
درست میکنه. پس اگه شما یه جدول یا یه تنظیم خاصی رو تویtemplate1
ایجاد کنین، تمام پایگاه دادههای جدیدی که از اون به بعد میسازین، اون جدول یا تنظیم رو به ارث میبرن. این یه ابزار قدرتمند برای استانداردسازی پایگاه دادههاتونه.template0
: اینم یه قالبه، ولی یه قالب دستنخورده و تمیز. یه جورایی نسخه «تنظیمات کارخانه» محسوب میشه. گاهی اوقات ممکنه شماtemplate1
رو خراب کنین (مثلا یه چیزی توش اضافه کنین که نباید میکردین). از اونجایی که برای ساختن یه کپی از یه قالب، نباید هیچ اتصال دیگهای به اون قالب وجود داشته باشه، اگهtemplate1
خراب بشه، درست کردنش سخته. اینجاtemplate0
به کمکتون میاد. میتونینtemplate1
رو حذف کنین و یهtemplate1
جدید از رویtemplate0
بسازین.
پس به طور خلاصه:
postgres
: برای اتصال اولیه.template1
: قالب پیشفرض برای ساخت پایگاه دادههای جدید.template0
: نسخه پشتیبان و تمیز از قالب، برای روز مبادا.
کپی کردن یک پایگاه داده از یه سرور به سرور دیگه
یکی از کارهای خیلی رایج، کپی کردن یه پایگاه داده از یه محیط به محیط دیگهست. مثلا از سرور اصلی (Production) به یه سرور تستی (Development) تا بتونین بدون ریسک، روی دادههای واقعی کار کنین. راههای مختلفی برای این کار هست.
روش اول: استفاده از pg_dump
و psql
(روش کلاسیک)
این روش خیلی محبوبه و از دو تا ابزار خط فرمان استفاده میکنه: pg_dump
برای گرفتن خروجی (بکاپ) و psql
برای برگردوندن اون خروجی (ریستور).
میشه این دوتا رو با هم ترکیب کرد تا بدون ساختن فایل واسطه، کار انجام بشه. به این کار میگن «پایپ کردن» (Piping) که با علامت |
انجام میشه.
pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname
بیاین این دستور رو بشکافیم:
pg_dump
: ابزار بکاپگیری.-C
: بهpg_dump
میگه که دستورCREATE DATABASE
رو هم توی خروجی بذاره. اینجوری لازم نیست پایگاه داده مقصد رو از قبل بسازیم.-h localhost
: میگه به سروری که روی همین کامپیوتر (localhost) هست وصل شو.-U localuser
: با کاربرlocaluser
وصل شو.dbname
: اسم پایگاه دادهای که میخوایم ازش بکاپ بگیریم.|
: این علامت جادوییه. خروجی دستور سمت چپش رو به عنوان ورودی به دستور سمت راستش میده.psql
: ابزار کلاینت پستگرس که اینجا برای ریستور کردن استفاده میشه.-h remotehost
: میگه به سرور مقصد که آدرسشremotehost
هست وصل شو.-U remoteuser
: با کاربرremoteuser
به سرور مقصد وصل شو.
اگه پایگاه داده بزرگ باشه یا سرعت شبکه کم باشه، شاید بهتر باشه اول خروجی رو توی یه فایل ذخیره کنین، فایل رو فشرده کنین، به سرور مقصد منتقل کنین و بعد اونجا ریستور کنین.
# روی سرور مبدا
pg_dump -C -Fp -f dump.sql -U postgres some_database_name
scp dump.sql development:
rm dump.sql
# روی سرور مقصد
ssh development
psql -U postgres -f dump.sql
روش دوم: استفاده از تونل فشرده با SSH
اگه میخواین همزمان هم کار فشردهسازی و هم انتقال امن رو انجام بدین، میتونین از این روش استفاده کنین:
pg_dump -C dbname | bzip2 | ssh remoteuser@remotehost "bunzip2 | psql dbname"
اینجا خروجی pg_dump
اول با bzip2
فشرده میشه، بعد از طریق یه اتصال امن ssh
به سرور مقصد فرستاده میشه، اونجا از حالت فشرده خارج میشه (bunzip2
) و در نهایت با psql
ریستور میشه.
روش سوم: pg_basebackup
(برای حرفهایها و دیتابیسهای بزرگ)
این ابزار برای وقتیه که شما میخواین یه کپی کامل و دقیق از کل «کلاستر» پایگاه داده بگیرین، نه فقط یه پایگاه داده خاص. این روش سریعتره، مخصوصا برای دیتابیسهای خیلی بزرگ. این کار یه جورایی مثل کلون کردن هارد دیسک سرور پایگاه دادهست.
برای استفاده از این روش باید یه سری تنظیمات روی سرور مبدا انجام بدین:
- در فایل
postgresql.conf
، گزینهlisten_addresses
رو روی'*'
تنظیم کنین تا سرور از آیپیهای دیگه هم اتصال قبول کنه. - باز هم در همین فایل،
wal_level
رو حداقل رویreplica
بذارین. - و
max_wal_senders
رو روی یه عددی بزرگتر از صفر (مثلا ۱ یا بیشتر) تنظیم کنین. - در فایل
pg_hba.conf
، یه خط اضافه کنین که به سرور مقصد اجازه اتصال برای «replication» (همانندسازی) بده.host replication postgres DST_IP/32 trust
(به جایDST_IP
باید آیپی سرور مقصد رو بذارین). - بعد از این تغییرات، سرور پستگرس رو ریستارت کنین.
حالا روی سرور مقصد:
- سرویس پستگرس رو متوقف کنین (
sudo service postgresql stop
). - تمام محتویات پوشه دادههای پستگرس رو پاک کنین (مثلا
/var/lib/postgresql/12/main/*
). مواظب باشین این کار رو روی سرور اشتباهی انجام ندین! - دستور
pg_basebackup
رو اجرا کنین:
sudo -u postgres pg_basebackup -h SRC_IP -U postgres -D /var/lib/postgresql/12/main/ --progress
(به جای SRC_IP
آیپی سرور مبدا رو بذارین).
- بعد از اینکه کارش تموم شد، سرویس پستگرس رو روی سرور مقصد روشن کنین (
sudo service postgresql start
).
حالا شما یه کپی دقیق از کل سرور مبدا روی سرور مقصد دارین.
روش چهارم: استفاده از رابط گرافیکی (GUI) مثل pgAdmin
اگه با خط فرمان راحت نیستین، همیشه میتونین از ابزارهای گرافیکی استفاده کنین. با pgAdmin مراحل خیلی سادهست:
- به هر دو سرور مبدا و مقصد وصل بشین.
- روی پایگاه داده مبدا کلیک راست کنین و گزینه «Backup» رو بزنین. یه فایل بکاپ براتون میسازه.
- روی سرور مقصد کلیک راست کنین، «Create» و بعد «Database» رو بزنین و یه پایگاه داده جدید با همون مشخصات پایگاه داده مبدا بسازین.
- روی پایگاه داده جدیدی که ساختین کلیک راست کنین و «Restore» رو بزنین. فایل بکاپی که در مرحله ۲ ساختین رو بهش بدین تا اطلاعات رو برگردونه.
بخش ششم: چطوری سرعت رو بالا نگه داریم؟ نگاهی به بهینهسازی عملکرد
گاهی اوقات ممکنه پایگاه داده شما کند بشه، مخصوصا وقتی حجم دادهها زیاد میشه و تعداد کاربرها بالا میره. به این وضعیت میگن «بار بالا» (High Load). مدیریت این وضعیت یه بحث خیلی بزرگه، ولی بیاین چند تا نکته کلیدی رو با هم مرور کنیم.
۱. اول بفهمین دیتابیس داره چیکار میکنه.
مشکلات عملکردی معمولا به خاطر چند تا «کوئری» (Query) یا همون پرسوجوی سنگین و پرهزینهست که زیاد اجرا میشن. اولین قدم اینه که این کوئریها رو پیدا کنین.
۲. از EXPLAIN ANALYZE
استفاده کنین.
این یکی از قدرتمندترین ابزارهای شماست. وقتی قبل از هر کوئری SELECT
، عبارت EXPLAIN ANALYZE
رو بنویسین، پستگرس به جای اجرای عادی کوئری، به شما یه گزارش کامل از «نقشه اجرا» (Execution Plan) اون کوئری میده. یعنی بهتون میگه که برای پیدا کردن جواب، دقیقا چه قدمهایی رو برداشته و هر قدم چقدر زمان برده.
۳. حواستون به «Sequential Scans» باشه.
وقتی توی خروجی EXPLAIN
دیدین که روی یه جدول بزرگ داره «Sequential Scan» انجام میشه، باید حواستون رو جمع کنین. این یعنی پستگرس داره کل جدول رو ردیف به ردیف از اول تا آخر میخونه تا داده مورد نظر شما رو پیدا کنه. این کار برای جدولهای بزرگ خیلی خیلی کنده.
۴. از ایندکس (Index) استفاده کنین.
راهحل Sequential Scan معمولا ساختن «ایندکس» هست. ایندکس مثل فهرست آخر یه کتاب قطوره. شما برای پیدا کردن یه مطلب، کل کتاب رو صفحه به صفحه نمیخونین، بلکه میرین سراغ فهرست و مستقیم به صفحه مورد نظر میرین. ایندکس هم برای پایگاه داده همین کار رو میکنه. شما روی ستونهایی که معمولا توی شرط WHERE
کوئریهاتون استفاده میکنین، ایندکس میسازین. اینجوری پستگرس میتونه خیلی سریعتر ردیفهای مورد نظر رو پیدا کنه.
۵. VACUUM
و ANALYZE
رو فراموش نکنین.
وقتی شما دادهها رو توی پستگرس UPDATE
یا DELETE
میکنین، فضای اونها فورا آزاد نمیشه. به مرور زمان این فضاهای مرده جمع میشن و باعث میشن جدولها بزرگتر از اندازه واقعیشون بشن (به این میگن Bloat). دستور VACUUM
این فضاهای مرده رو تمیز و قابل استفاده مجدد میکنه.
دستور ANALYZE
هم اطلاعات آماری در مورد توزیع دادهها توی جدولها جمعآوری میکنه. پستگرس از این آمارها استفاده میکنه تا بهترین و بهینهترین نقشه اجرا رو برای کوئریهای شما انتخاب کنه.
در خیلی از تنظیمات پیشفرض، سرویس «autovacuum» فعاله و این کارها رو خودکار انجام میده، ولی خوبه که بدونین این دستورها وجود دارن و گاهی اوقات لازمه به صورت دستی اجرا بشن.
بخش هفتم: پرسش و پاسخ (سوالات متداول شما)
در طول این مقاله به سوالات مختلفی اشاره کردیم. بیاین اینجا چند تا از مهمترینهاشون رو به صورت خلاصه مرور کنیم.
سوال ۱: بالاخره پستگرسکیوال یه زبانه یا یه سرور؟
پستگرسکیوال یک نرمافزار مدیریت پایگاه داده هست که به عنوان یک سرور عمل میکنه. این نرمافزار، زبان SQL (زبان استاندارد کوئرینویسی) رو میفهمه و اجرا میکنه. پس خودش زبان نیست، بلکه اجراکننده زبانه.
سوال ۲: این «سرورهایی» که توی pgAdmin میبینم چی هستن؟ یعنی چند تا کامپیوتر مختلفن؟
هر «سرور» توی pgAdmin نشوندهنده یک اتصال به یک نمونه (instance) از سرور پایگاه داده پستگرسکیواله. این سرور میتونه روی کامپیوتر خود شما باشه (localhost) یا روی یه کامپیوتر دیگه در شبکه یا اینترنت. شما میتونین به چندین سرور مختلف به صورت همزمان متصل باشین.
سوال ۳: من پایگاه دادههایی به اسم postgres
و template1
میبینم. اینها چی هستن و میتونم پاکشون کنم؟
postgres
: پایگاه داده پیشفرض برای اتصال اولیه ابزارها و کاربران. بهتره پاکش نکنین چون خیلی از برنامهها به وجودش تکیه میکنن.template1
: قالبی که تمام پایگاه دادههای جدید از روی اون کپی میشن. پاک کردنش ایده خوبی نیست، مگه اینکه بخواین از رویtemplate0
(قالب پشتیبان) یه نسخه جدید ازش بسازین.
سوال ۴: سادهترین راه برای کپی کردن یه پایگاه داده از کامپیوتر خودم به یه سرور دیگه چیه؟
برای دیتابیسهای کوچیک و متوسط، استفاده از ترکیب pg_dump
و psql
با پایپ کردن خیلی ساده و سریعه:pg_dump -C -h [آدرس مبدا] -U [کاربر مبدا] [اسم دیتابیس مبدا] | psql -h [آدرس مقصد] -U [کاربر مقصد] [اسم دیتابیس مقصد]
سوال ۵: سرور پستگرس من بعد از آپدیت سیستمعامل روشن نمیشه و کلی خطای عجیب در مورد nvidia
و vboxdrv
میبینم. مشکل چیه؟
به احتمال خیلی زیاد مشکل از خود پستگرس نیست. این خطاها نشون میدن که کل سیستمعامل شما بعد از آپدیت دچار بیثباتی شده و درایورهای مهمی بارگذاری نشدن. در چنین شرایطی، سیستم نمیتونه محیط پایداری برای اجرای سرویس پستگرس فراهم کنه. شما باید اول مشکلات سیستمعامل و درایورهاتون رو حل کنین.
سوال ۶: میخوام وصل بشم ولی خطای authentication failed
یا could not connect to server
میگیرم. اولین چیزایی که باید چک کنم چی هستن؟
- آیا سرویس پستگرس اصلا روشنه؟ با دستورهایی مثل
systemctl status postgresql
یاpg_lsclusters
وضعیتش رو چک کنین. - آیا سطح دسترسی پوشه دادهها درسته؟ همونطور که دیدیم، پستگرس به این موضوع خیلی حساسه. لاگهای پستگرس رو چک کنین تا ببینین خطایی در این مورد وجود نداره.
- آیا تداخل پورت وجود نداره؟ مطمئن بشین که هیچ برنامه دیگهای (مثلا یه نسخه دیگه از پستگرس) در حال استفاده از همون پورتی که شما میخواین بهش وصل بشین (معمولا
5432
) نیست. - آیا اطلاعات اتصال (آدرس سرور، نام کاربری، پسورد) رو درست وارد میکنین؟ این مورد خیلی ساده به نظر میرسه ولی زیاد اتفاق میفته
منابع
- [2] After Upgrading, Can’t Boot “Failed to start PostgreSQL database server” – Computer Used for Work – Support – Manjaro Linux Forum
- [4] Default database named postgres on Postgresql server – Stack Overflow
- [6] linux – managing high load of a postgresql database – Server Fault
- [8] PostgreSQL: Why psql can’t connect to server? – Stack Overflow
- [10] p1000 authentication failed against database server · prisma/prisma · Discussion #8925 · GitHub
- [1] Noob Question: What are “servers” in postgreSQL/pgAdmin? : r/PostgreSQL
- [3] PostgreSQL: The world’s most advanced open source database
- [5] sql – If I’m using PostgreSQL, do I need a server too? Like AWS RDS? – Stack Overflow
- [7] PostgreSQL: Downloads
- [9] Copying PostgreSQL database to another server – Stack Overflow
دیدگاهتان را بنویسید