টেবিলে নালামযোগ্য কলাম যুক্ত করতে 10 মিনিটেরও বেশি সময় লাগে


11

টেবিলে নতুন কলাম যুক্ত করতে আমার সমস্যা আছে have
আমি এটি কয়েকবার চালানোর চেষ্টা করেছি, তবে 10 মিনিটেরও বেশি দৌড়ানোর পরে, লক টাইমের কারণে আমি কোয়েরিটি বাতিল করার সিদ্ধান্ত নিয়েছি।

ALTER TABLE mytable ADD mycolumn VARCHAR(50);

দরকারী তথ্য:

  • পোস্টগ্রিএসকিউএল সংস্করণ: 9.1
  • সারি সংখ্যা: ~ 250 কে
  • কলামের সংখ্যা: 38
  • শনাক্তযোগ্য কলামগুলির সংখ্যা: 32
  • সীমাবদ্ধতার সংখ্যা: 5 (1 পিকে, 3 এফকে, 1 অনন্য)
  • সূচকের সংখ্যা: 1
  • ওএস প্রকার: দেবিয়ান স্কুইজ 64

পোস্টগ্রিএসকিউএল যেভাবে নালামযোগ্য কলামগুলি পরিচালনা করে (হিপটপলহিডারের মাধ্যমে) তার সম্পর্কে আকর্ষণীয় তথ্য পেয়েছি ।

আমার প্রথম অনুমানটি হ'ল যেহেতু এই টেবিলটিতে ইতিমধ্যে 8-বিট সহ 32 টি নালাম কলাম রয়েছে MAXALIGN, হিপটপলহাইডারটি 4 বাইট দৈর্ঘ্যের (যাচাই করা হয়নি, এবং আমি কীভাবে এটি করব তা জানি না)।

সুতরাং একটি নতুন অযোগ্য কলাম যুক্ত করার জন্য একটি নতুন 8-বিট যুক্ত করতে প্রতিটি সারিতে HeapTupleHeader এর একটি আপডেটের প্রয়োজন MAXALIGNহতে পারে, যা কার্য সম্পাদনের সমস্যার কারণ হতে পারে।

সুতরাং আমার অনুমানটি সত্য হতে পারে কিনা তা পরীক্ষা করার জন্য, আমি একটি নালাম কলামগুলির মধ্যে একটি পরিবর্তন করতে চেষ্টা করেছি (যা বাস্তবে প্রকৃতপক্ষে ছোট নয়))

ALTER TABLE mytable ALTER myothercolumn SET NOT NULL;

দুর্ভাগ্যক্রমে, এই পরিবর্তনটি খুব দীর্ঘ সময় নেয়, 5 মিনিটেরও বেশি সময়, তাই আমি এটি বাতিলও করেছি।

এই পারফরম্যান্স ব্যয়ের কারণ কী হতে পারে সে সম্পর্কে আপনার কি ধারণা আছে?


1
ঠিক আছে, আমি আপনাকে এর অংশটি বলতে পারি: কলামের টাইপটিকে অন্য প্রকারে পরিবর্তন করা যা বাইনারি সুসংগত নয় প্রকৃতপক্ষে একটি নতুন কলাম তৈরি করে, তথ্য অনুলিপি করে এবং পুরানো কলামটি বাদ দেওয়া হিসাবে সেট করে। তবে, SET NOT NULLপ্রকারটি পরিবর্তন করে না, এটি কেবল একটি সীমাবদ্ধতা যুক্ত করে - তবে সীমাবদ্ধতার বিষয়টি অবশ্যই টেবিলের বিপরীতে পরীক্ষা করা উচিত এবং এর জন্য একটি পূর্ণ টেবিল স্ক্যান প্রয়োজন requires 9.4 দুর্বল লকগুলি নিয়ে এর মধ্যে কয়েকটি ক্ষেত্রে উন্নতি করে তবে এটি এখনও বেশ হেভিওয়েট।
ক্রেগ রিঞ্জার

1
এটি ধীরে ধীরে সঞ্চালিত হচ্ছে এমন সন্দেহ করার আগে, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে অলটার টেবিলে কেবল একটি লকের জন্য অপেক্ষা করা হচ্ছে না। যদি আপনি পরীক্ষা করে থাকেন তবে প্রশ্নটিতে এটি উল্লেখ করুন।
ড্যানিয়েল ভ্যারিট

ধন্যবাদ ক্রেগ এবং ড্যানিয়েল। আমি যখন অলটার কমান্ডটি চালাচ্ছি, এটি "সত্য" অপেক্ষা করে pg_stat_activity তে উপস্থিত হবে, আমি মনে করি এর অর্থ এটি একটি লকের জন্য অপেক্ষা করছে !? এটা চেক করার জন্য ভাল উপায়? যাইহোক, এই পরিবর্তনটি চালানোর আগে, সবকিছু ঠিকঠাক হয়ে যায়, তবে শুরু করার কয়েক সেকেন্ড পরে, তালার সংখ্যা বেড়ে যায়

আরও ভাল দৃষ্টির জন্য wiki.postgresql.org/wiki/Lock_d dependency_inifications এ ক্যোয়ারীটি চেষ্টা করে দেখুন। হয় আপনার লম্বা লেনদেন যা প্রতিশ্রুতি দিতে ভুলে যায় বা এই টেবিলটির সাথে ভারী ক্রিয়াকলাপ যা এটি সর্বদা ব্যস্ত রাখে।
ড্যানিয়েল ভ্যারিট

ডিবিএএসইতে আরও ভাল ফিট হতে পারে
এরউইন ব্র্যান্ডসটেটার

উত্তর:


8

এখানে বেশ কয়েকটি ভুল ধারণা রয়েছে:

নাল বিটম্যাপ হয় না গাদা tuple হেডার অংশ। প্রতি ডকুমেন্টেশন:

একটি স্থির আকারের শিরোলেখ রয়েছে (বেশিরভাগ মেশিনে 23 বাইট দখল করা), তার পরে একটি alচ্ছিক নাল বিটম্যাপ ...

আপনার 32 টি অপ্রয়োগযোগ্য কলাম দুটি কারণে সন্দেহজনক নয়:

  • নাল বিটম্যাপটি সারি প্রতি যুক্ত করা হয় এবং কেবলমাত্র সারিটিতে কমপক্ষে একটি আসল NULLমান থাকে। নলাবল কলামগুলির সরাসরি প্রভাব নেই, কেবল আসল NULLমানগুলি। যদি নাল বিটম্যাপ বরাদ্দ করা হয় তবে এটি সর্বদা সম্পূর্ণ বরাদ্দ হয় (সমস্ত বা কিছুই নয়)। নাল বিটম্যাপের আসল আকারটি প্রতি কলামে 1 বিট, পরবর্তী বাইট পর্যন্ত গোল হয়প্রতি বর্তমান স্যুইস কোড:

    #define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
  • নাল বিটম্যাপটি হ্যাপ টিপল শিরোনামের পরে বরাদ্দ করা হয় এবং তার পরে একটি Oচ্ছিক ওআইডি এবং তারপরে ডেটা সারি করা হয়। একটি ওআইডি বা সারি ডেটার শুরু t_hoffশিরোনাম দ্বারা নির্দেশিত হয় । প্রতি মন্তব্য উত্স কোড :

    মনে রাখবেন যে t_hoff অবশ্যই MAXALIGN এর একাধিক হতে হবে।

  • হ্যাপ টিপল শিরোলেখের পরে একটি ফ্রি বাইট রয়েছে, যা 23 বাইট দখল করে। সুতরাং 8 টি কলাম পর্যন্ত সারিগুলির নাল বিটম্যাপ কার্যকরভাবে কোনও অতিরিক্ত ব্যয় ছাড়াই আসে। সারণীতে নবম কলামের সাথে আরও একটি typically৪ টি কলাম সরবরাহ করার জন্য আরও t_hoffএকটি MAXALIGN(সাধারণত 8) বাইট উন্নত করা হয়েছে । সুতরাং পরবর্তী সীমানা 72 কলামে হবে।

পোস্টগ্রিসএসকিউএল ডাটাবেস ক্লাস্টারের নিয়ন্ত্রণ তথ্য প্রদর্শন করতে ( MAXALIGNউদাহরণ সহ ), উদাহরণস্বরূপ একটি ডেবিয়ান মেশিনে পোস্টগ্রাস 9.3 ইনস্টল করার জন্য:

    sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main

আপনার উদ্ধৃত সম্পর্কিত উত্তরগুলিতে আমি নির্দেশাবলী আপডেট করেছি ।

আপনার সমস্ত ALTER TABLEবক্তব্য পুরো টেবিলের পুনর্লিখনকে (যা সম্ভবত এটি করে, কোনও ডেটা টাইপ পরিবর্তন করে) ট্রিগার করে, 250 কে আসলেই তেমন কিছু না এবং কোনও অর্ধপথের শালীন মেশিনে কয়েক সেকেন্ডের ব্যাপার হবে (যদি না সারি অস্বাভাবিকভাবে বড় হয়) । 10 মিনিট বা তারও বেশি সম্পূর্ণ ভিন্ন সমস্যা নির্দেশ করে। আপনার বক্তব্যটি সম্ভবত টেবিলে একটি লক পাওয়ার জন্য অপেক্ষা করছে।

এন্ট্রিগুলির ক্রমবর্ধমান সংখ্যার pg_stat_activityঅর্থ আরও উন্মুক্ত লেনদেন - টেবিলের একযোগে অ্যাক্সেস নির্দেশ করে (সম্ভবত:) যা অপারেশন শেষ হওয়ার জন্য অপেক্ষা করতে হবে।

অন্ধকারে কয়েকটি শট

সম্ভাব্য টেবিল ফোটা পরীক্ষা করুন, একটি নম্র VACUUM mytableবা আরও আক্রমণাত্মক চেষ্টা করুন VACUUM FULL mytable- যা একই সমঝোতার সমস্যাগুলির মুখোমুখি হতে পারে, যেহেতু এই ফর্মটিও একটি এক্সক্লুসিভ লক অর্জন করে। পরিবর্তে আপনি pg_repack চেষ্টা করতে পারেন ...

আমি সূচকগুলি, ট্রিগারগুলি, বিদেশী কী বা অন্যান্য সীমাবদ্ধতাগুলি বিশেষত কলামের সাথে জড়িতদের দ্বারা সম্ভাব্য সমস্যাগুলি পর্যবেক্ষণ করে শুরু করব। বিশেষত কোনও দূষিত সূচক জড়িত থাকতে পারে? চেষ্টা করুন REINDEX TABLE mytable;বা DROPতাদের সকল এবং ALTER TABLE একই লেনদেনের পরে তাদের আবার যুক্ত করুন ।

রাতে বা যখনই খুব বেশি বোঝা নেই তখন কমান্ড চালানোর চেষ্টা করুন।

একটি ব্রুট ফোর্স পদ্ধতি হ'ল সার্ভারের অ্যাক্সেস বন্ধ করা, তারপরে আবার চেষ্টা করুন:

এটি পিন করতে সক্ষম না হয়ে বর্তমান সংস্করণে আপগ্রেড করা বা বিশেষত আসন্ন 9.4 এ সহায়তা করতে পারে। বড় টেবিলের জন্য এবং লকিংয়ের বিশদের জন্য বেশ কয়েকটি উন্নতি হয়েছে। তবে আপনার ডিবিতে যদি কিছু ভাঙা থাকে তবে আপনার সম্ভবত প্রথমে এটি বের করা উচিত।


2
এটি প্রায় অবশ্যই লকস তবে, পরীক্ষা হিসাবে, আপনি সর্বদা টেবিলের একটি অনুলিপি তৈরি করতে পারেন এবং এটির পরিবর্তনের চেষ্টা করতে পারেন। যদি এটি খুব বেশি সময় না নেয় তবে আপনি জানেন যে এটি আসল পরিবর্তন নয় যা সমস্যা।

এরউইন ব্যাখ্যার জন্য ধন্যবাদ। আমি মনে করি আপনি ঠিক বলেছেন, এটি লকের সমস্যা বলে মনে হচ্ছে। আমি যখন pg_stat_activity পরীক্ষা করি, আমি দেখতে পাব যে আমার ALTER এর একটি "অপেক্ষা" সত্য। আমি কী বুঝতে পারি না কেন অলটার টেবিলে লকটি পাচ্ছে না, কারণ আমি যখন কোনও জিজ্ঞাসা চালাচ্ছি না তখনও কারণটি এটি পেতে পারে না বলে মনে হয়। তবে যতক্ষণ না আমার ALTER চালানো শুরু হবে, অন্যান্য সমস্ত ক্যোয়ারী এটি শেষ হওয়ার জন্য অপেক্ষা করছে। সুতরাং, ক্রিয়াকলাপটি ইঙ্গিত দেয় বলে মনে হয় যে ALTER অন্যান্য সমস্ত ক্যোয়ারী লক করে, তবে এটিও ইঙ্গিত করে যে ALTER লকটি পায়নি। আমার মনে হয় এমন কিছু আছে যা আমি বুঝতে পারি না !?

@ ম্যাথিয়েউভেরেচিয়া: আপনি কি রিচার্ডের পরামর্শ দিয়েছিলেন পরীক্ষার চেষ্টা করেছিলেন?
এরউইন ব্র্যান্ডসেটেটার

1
আমি সবেমাত্র আমার টেবিলে একটি নতুনকে ক্লোন করেছি (pg_dump -> pg_sql সহ)। নতুন কলামটি 50 মিমিগুলিতে সঠিকভাবে যুক্ত হয়েছে, যা লক সমস্যাটিকে নিশ্চিত করে। যাইহোক, এখনও ALL কেন সত্যই স্ট্যান্ডার্ড ডিবি ক্রিয়াকলাপ দিয়ে লক পেতে পারে না তা বুঝতে পারি না।

1
@ এরউইন ব্র্যান্ডস্টেটর আমি আপনার পরামর্শগুলি অনুসরণ করেছি এবং একটি ভ্যাকুয়াম চেষ্টা করেছি, তারপরে একটি রিইন্ডেক্স। REINDEX এছাড়াও অবরুদ্ধ ছিল, কারণ এটি লক অর্জন করতেও অক্ষম ছিল .. কিছু তদন্তের পরে, সমস্যাটি আপনার চেয়ে আমরা আরও সহজ হয়েছি .. একটি সপ্তাহ বাকি ছিল <IDLE> একটি খোলা লেনদেনের সাথে সমস্যার সমাধান হয়েছে, ধন্যবাদ সব কিছুর জন্য, তথ্যগুলি খুব দরকারী ছিল।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.