তালিকাবদ্ধ কলাম সহ একটি বড় টেবিলের টেবিলটি পরিবর্তন করুন


14

আমার কাছে একটি ভিউচারার (20) কলাম সহ একটি বড় টেবিল রয়েছে এবং আমার এটি পরিবর্তন করতে হবে যাতে ভিশচার (50) কলামটি হয়। সাধারণত, এই নির্দিষ্ট টেবিলে একটি অল্টার টেবিল সম্পাদন (একটি টিআইএনআইএনটি যোগ করা) প্রায় 90-120 মিনিট সময় নেয়, সুতরাং আমি কেবলমাত্র শনিবার বা রবিবার রাতে এটি করতে পারি যে ডাটাবেসের ব্যবহারকারীদের উপর প্রভাব ফেলতে না পারে। যদি সম্ভব হয় আমি তার আগে এই পরিবর্তনটি করতে চাই।

কলামটিও সূচিবদ্ধ, যা আমি অনুমান করি যে বিকল্পটি আস্তে আস্তে আস্তে আস্তে আস্তে আস্তে টেবিল কমিয়ে আনা হবে, কারণ কলামের দৈর্ঘ্য সংশোধন করার পরে এটি সূচকটি পুনরায় তৈরি করতে হবে।

ওয়েব অ্যাপটি একটি মাইএসকিউএল প্রতিলিপি পরিবেশে (26 দাস এবং এক মাস্টার) সেট আপ করা হয়েছে। আমি একবার কোথাও পড়ে মনে পড়েছি যে একটি পদ্ধতি হ'ল প্রতিটি গোলামের উপর প্রথমে ALL TABLE করা (ব্যবহারকারীদের উপর প্রভাব হ্রাস করা), তারপরে মাস্টারের উপর এটি করা, তবে সে কি দাসদের কাছে ALTER TABLE কমান্ডটি প্রতিলিপি দেওয়ার চেষ্টা করবে না?

সুতরাং আমার প্রশ্নটি: আমার ব্যবহারকারীদের সর্বনিম্ন ব্যাঘাতের সাথে এই টেবিলটি সংশোধন করার সর্বোত্তম উপায় কী?

সম্পাদনা: সারণীটি ইনোডিবি।


সেই ক্ষুদ্র কলামটি যুক্ত করার অর্থ আসলে একটি ডিফল্ট মান সহ একটি কলাম যুক্ত করা? কারণ বিশাল টেবিলে এটি করতে দীর্ঘ সময় লাগতে পারে ..
মেরিয়ান

উত্তর:


13

আপনি যদি কিছুটা দুঃসাহসী হন তবে আপনি দেখতে পারেন এমন পর্যায়গুলিতে ALTER TABLE সম্পাদন করে আপনি বিষয়গুলি আপনার হাতে নিয়ে যেতে পারেন। ধরুন আপনি যে টেবিলটি পরিবর্তন করতে চান তাকে ওয়ার্কিং টেবিল বলে। আপনি এই পর্যায়ে পরিবর্তনগুলি সম্পাদন করতে পারেন:

#
#  Script 1
#  Alter table structure of a single column of a large table
#
CREATE TABLE WorkingTableNew LIKE WorkingTable;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT * FROM WorkingTable;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;

আপনি সমস্ত দাসদের উপর এটি সম্পাদন করতে পারেন। মাস্টার কি ??? আপনি কীভাবে এটি দাসদের প্রতিলিপি করা থেকে আটকাবেন। সহজ: এসকিউএলকে মাস্টারের বাইনারি লগগুলিতে প্রেরণ করবেন না। কেবলমাত্র টেবিল স্টাফ করার আগে সেশনটিতে বাইনারি লগিং বন্ধ করুন:

#
#  Script 2
#  Alter table structure of a single column of a large table
#  while preventing it from replicating to slaves
#
SET SQL_LOG_BIN = 0;
CREATE TABLE WorkingTableNew LIKE WorkingTable;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT SQL_NO_CACHE * FROM WorkingTable;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;

কিন্তু অপেক্ষা করো !!! এই কমান্ডগুলি প্রক্রিয়া করার সময় যে কোনও নতুন ডেটা আসে যা সম্পর্কে ??? ক্রিয়াকলাপের শুরুতে টেবিলটির নতুন নামকরণের কৌশলটি করা উচিত। সে ক্ষেত্রে নতুন ডেটা প্রবেশ করা রোধ করতে এই কোডটিকে কিছুটা পরিবর্তন করতে দিন:

#
#  Script 3
#  Alter table structure of a single column of a large table
#  while preventing it from replicating to slaves
#  and preventing new data from entering into the old table
#
SET SQL_LOG_BIN = 0;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
CREATE TABLE WorkingTableNew LIKE WorkingTableOld;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT SQL_NO_CACHE * FROM WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;
  • স্ক্রিপ্ট 1 এমন কোনও গোলামের উপর চালানো যেতে পারে যা বাইনারি লগ সক্ষম করে না
  • স্ক্রিপ্ট 2 বাইনারি লগ সক্ষম আছে এমন যে কোনও গোলামের উপর কার্যকর করা যেতে পারে
  • স্ক্রিপ্ট 3 কোনও মাস্টার বা অন্য কোথাও প্রয়োগ করা যেতে পারে

একবার চেষ্টা করে দেখো !!!


2
একটি সমস্যা যা আমি দেখতে পাচ্ছি তা হল যদি টেবিলটিতে একটি 'অটো_সংশোধন' ক্ষেত্র থাকে। আমি একটি প্রাথমিক পরীক্ষা করেছি এবং অবাক হয়ে দেখেছি যে টেবিলটি তৈরি করুন .. লাইক স্বয়ংক্রিয় সংযোজন মানটি নতুন টেবিলটিতে অনুলিপি করে না
ডেরেক

1
@ ডিস্টেস্ট: ভাল ক্যাচ এবং দুর্দান্ত মন্তব্য !!!। আমি বিশ্বাস করি আপনি তথ্য_সেমিটা.সামগ্রী কলাম কাস্টম আউটপুট থেকে ক্রয় মানটি পুনরুদ্ধার করতে পারেন। যদি টেবিলটির AUTO_INCREMENT ক্ষেত্র না থাকে, তবে তথ্য_সেমি.টি.টেবিলগুলিতে AUTO_INCREMENT কলামটি NULL হবে। অন্যথায়, এটিতে প্রয়োজনীয় আউটপুট ক্রিমেন্ট থাকবে। আমি অনুমান করি যে এটি নন-নুল মানটি বের করতে এবং টেবিল ওয়ার্কিংসেট অ্যাটোরোপ্রেমেন্ট = <someumber> করতে করতে স্ক্রিপ্ট করা যেতে পারে; টেম্প টেবিলটির নামকরণের ঠিক আগে ওয়ার্কিংসেটে ফিরে আসুন।
RolandoMySQLDBA

@ রোল্যান্ডোমাইএসকিউএলডিবিএ অন্য যে কাজটি করা যায় তা হ'ল আপনি "টেবিল ওয়ার্কিং টেবিল তৈরি করুন" বিবৃতিটি অনুলিপি করে ওয়ার্কিং টেবিল নিউ তৈরি করেন এবং আপনার জন্য নিরাপদ এমন একটি সংখ্যা দ্বারা এটি চালিয়ে অটো_ক্রিমেন্ট ক্ষেত্রের মান পরিবর্তন করুন এবং কলামটি ভারচারে পরিবর্তন করুন (৫০) ), এবং তারপরে উভয় পুনরায় নামকরণ একক বিবৃতিতে করুন "টেবিলের পুনরায় নাম টেবিল ওয়ার্কিং টেবিল ওয়ার্কিং টেবিল, পুনরায় টেবিলের নাম পুনরায় নামকরণ ওয়ার্কিং টেবিল থেকে ওয়ার্কিং টেবিল" একক কমান্ডে উভয় নাম চালানো ব্যর্থ হবে না তা নিশ্চিত করে (এটি টেডের জন্য প্রোড যা পরীক্ষাগুলির সংখ্যা নির্ধারণ করে) আপনি "সন্নিবেশ ... ..." কমান্ড থেকে করতে পারেন
গৌতম সোমানী

4

আমার কাছ থেকে অনুমান ডকুমেন্টেশন হবে যে কেবলমাত্র একটি দৈর্ঘ্যের সীমাবদ্ধতা বৃদ্ধি করায় varcharকলাম যুক্ত করার মতো সমস্যা হবে না:

কিছু ক্রিয়াকলাপের জন্য, একটি স্থান পরিবর্তনকারী টেবিলটি সম্ভব হয় যার জন্য অস্থায়ী টেবিলের প্রয়োজন হয় না:

তবে এ সম্পর্কে মন্তব্যগুলিতে এটি বিপরীত বলে মনে হচ্ছে এসও প্রশ্নের ।

সম্পাদনা

কমপক্ষে ৫.০-তে, আমি মনে করি যে আমি নিশ্চিত করতে পারি যে দৈর্ঘ্য বাড়ানোর জন্য একটি অস্থায়ী টেবিলের প্রয়োজন হয় (বা অন্য কোনও সমানে ব্যয়বহুল অপারেশন):

টেস্টবেড:

create table my_table (id int auto_increment primary key, varchar_val varchar(10));
insert into my_table (varchar_val)
select 'HELLO'
from (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s1,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s2,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s3,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s4,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s5,
     (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) s6;

ফলাফল:

alter table my_table modify varchar_val varchar(20);
Query OK, 1000000 rows affected (2.91 sec)

alter table my_table add int_val int;
Query OK, 1000000 rows affected (2.86 sec)

ভারচার ক্ষেত্রের আকার পরিবর্তন করতে আপনি নতুন আকারের চেয়ে বেশি নন কিনা তা পরীক্ষা করে নেওয়া জড়িত। আকার বৃদ্ধির জন্য এই চেকটি এখনই অপ্টিমাইজড হতে পারে।
বিলথোর

3

আমি ভেবেছিলাম, আমি যেহেতু এটি উল্লেখ করব ENGINE=INNODB

আপনার যদি বিদেশী কী বাধা থাকে তবে আপনি পুরানো টেবিলের (এখন নামকরণ করা হয়েছে) নির্দেশক আপনার সীমাবদ্ধতাকে ডাব্লু / ও পরিবর্তন করতে পারবেন না। আপনার পরে পরিবর্তন করতে হবে বা সময়কালের জন্য সীমাবদ্ধতাগুলি ফেলে দিতে হবে।


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