mysqldump থেকে ডেটা ধীর লোড গতি


21

আমি প্রায় 30 টি টেবিল সহ একটি মাঝারি আকারের মাইএসকিউএল ডাটাবেস পেয়েছি, যার মধ্যে কয়েকটি 10 ​​মিলিয়ন রেকর্ড, কিছু 100 মিলিয়ন। mysqldumpসব টেবিল (পৃথক ফাইল মধ্যে) -এর মোটামুটি দ্রুত, হয়তো 20 মিনিট সময় লাগে। এটি প্রায় 15GB ডেটা উত্পন্ন করে। বৃহত্তম ডাম্প করা ফাইলগুলি 2 জিবি সীমার মধ্যে রয়েছে।

যখন আমি অন্য বাক্সে, একটি ছয়-কোর, 8 জিবি মেশিনে মাইএসকিউএলে ডেটা লোড করি তখন এটি চিরতরে লাগে। সহজেই 12 ঘন্টা ঘন্টা বা তার বেশি।

আমি কেবল ফাইলটি লোড করার জন্য মাইএসকিএল ক্লায়েন্ট চালাচ্ছি

mysql database < footable.sql

সরাসরি mysqldump এর বাইরে ফাইলের সাথে ump

mysqldump database foo > footable.sql

স্পষ্টতই আমি কিছু ভুল করছি। আমি কোথায় শুরু করব যাতে এটি একটি উপযুক্ত সময়ে শেষ করা যায়?

আমি ডাম্প বা লোড উভয়ের উপর কোনও সুইচ ব্যবহার করছি না।


আপনি আপনার ডাম্পের বোঝা চলাকালীন সময়ে বাইনারি লগিং নিষ্ক্রিয় করতে পারেন
Cédric PEINTRE

উত্তর:


22

আপনার বিবেচনার জন্য এই কয়েকটি বিষয় বিবেচনা করুন এবং ডাম্প তৈরি এবং এটি পুনরুদ্ধার করার ক্ষেত্রে তারা আপনাকে সহায়তা করতে পারে।

  1. Extended insertsডাম্প ব্যবহার করুন ।
  2. --tabবিন্যাসের সাথে ডাম্প করুন যাতে আপনি ব্যবহার করতে পারেন mysqlimportযা এর চেয়ে দ্রুত mysql < dumpfile
  3. একাধিক থ্রেড সহ প্রতিটি টেবিলের জন্য একটি আমদানি করুন।
  4. সম্ভব হলে একটি ভিন্ন ডাটাবেস ইঞ্জিন ব্যবহার করুন। ইনোডাবের মতো ভারি লেনদেনের ইঞ্জিনে আমদানি করা ভীষণ ধীর। মাইআইএসএএম এর মতো অ-লেনদেনের ইঞ্জিনে প্রবেশ করা অনেক দ্রুত is
  5. বিদেশী কী চেকগুলি বন্ধ করুন এবং স্ব-প্রতিশ্রুতি চালু করুন।
  6. আপনি যদি একক সবচেয়ে কার্যকর জিনিস আননডব করতে আমদানি করতে পারেন innodb_flush_log_at_trx_commit = 2তবে আমদানি চলাকালীন অস্থায়ীভাবে আপনার মাই সিএনএফতে রাখা উচিত । আপনার এসিডি লাগলে আপনি এটি আবার 1 এ রাখতে পারেন

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


innodb_flush_log_at_trx_commit = 2আমার দিনটি বাঁচানোর সাথে আপনার ইঙ্গিত । MB০০ এমবি ডাম্প (একক বৃহত লেনদেন হিসাবে) আমদানি করতে hours ঘন্টা প্রয়োজন হত তবে এই অস্থায়ী সেটিংয়ের সাথে এটি ৩০ মিনিটে সম্পন্ন হয়েছিল!
ড্যানিয়েল মার্শচল

1
'প্রবেশ' হিট করার 4 দিন পরে ডাম্প থেকে একটি 80gig ডাটাবেস লোড করার চেষ্টা করার আগে আপনি যে জিনিসগুলি চান তা জানতে পেরেছিলেন ... :)
দিমিত্রি ডিবি

7

আবদুলের উত্তর ছাড়াও , আমি --disable-keysবিকল্পটির গুরুত্বের উপর জোর দিতে চাই , যা টেবিলে সমস্ত ডেটা লোড না হওয়া পর্যন্ত কীগুলি বন্ধ করে দেয়। এই বিকল্পটি --optটগল অংশ হিসাবে সক্ষম করা হয়েছে , যা ডিফল্টরূপে সক্ষম করা হয়েছে, তবে এটি উল্লেখ করা গুরুত্বপূর্ণ বলে মনে করেছে।

যদি আপনি সন্নিবেশগুলির সময় কীগুলি এড়িয়ে না যান তবে সন্নিবেশ করা প্রতিটি সারি সূচকটি পুনর্নির্মাণ করবে। একটি অত্যন্ত ধীর প্রক্রিয়া।


- ডিস্কেবল-কীগুলি মাইএসকিলডাম্পের অংশ? নাকি পুনরায় লোড?
প্যাট ফেরেল

এটি ডাম্প ফাইলে যুক্ত করা হবে
ডেরেক ডাউনি

--optডিফল্ট হিসাবে আছে
jbertman

1
This option is effective only for nonunique indexes of MyISAM tables. It has no effect for other tables
এথান অ্যালেন

7

আমি ইদানীং এর সাথে অনেক কিছু করে আসছি। সমান্তরালভাবে আমদানি করে আপনি আমদানি কর্মক্ষমতা উন্নত করতে পারেন। মন্দা বেশিরভাগই I / O ভিত্তিক, তবে আপনি টেবিলগুলিতে ফেলে এবং তারপরে একবারে 4 বলে আমদানি করে 40% উন্নতি পেতে পারেন।

আপনি এর মত xargs দিয়ে এটি করতে পারেন:

ls *.sql -1c | xargs -P4 -I tbl_name sh -c "mysql --user=username --password database < tbl_name"

ফাইলগুলিকে মাইএসকিএলে চাপ দেওয়ার আগে গিজিপ করা কিছুটা ধীর করে না কারণ বেশিরভাগ আই / ও হ্রাস করা হয়। আমার টেবিলগুলি প্রায় 10: 1 পর্যন্ত সংকুচিত হয়েছিল, সুতরাং এটি ডিস্কের অনেক জায়গার সঞ্চয় করে।

আমি খুঁজে পেয়েছি যে ৪ টি মূল মেশিনে, 4 টি প্রক্রিয়া ব্যবহার করা সর্বোত্তম, যদিও 3 ব্যবহারের চেয়ে সামান্যতম ভাল better যদি আপনার এসএসডি বা একটি দ্রুত র‌্যাড থাকে, আপনি সম্ভবত আরও ভাল স্কেল করবেন।

আরও কিছু বিষয় লক্ষণীয়। আপনার যদি 4 কে সেক্টর ড্রাইভ থাকে তবে নিশ্চিত হয়ে নিন যে আপনার আছে key_cache_block_size=4096এবং আছে myisam_block_size=4K

যদি আপনি মাইআইএসএএম টেবিল ব্যবহার করেন তবে myisam_repair_threads = 2উচ্চতর বা উচ্চতর সেট করুন । এটি আপনার অতিরিক্ত কোরকে সূচকগুলি পুনর্নির্মাণে সহায়তা করবে।

নিশ্চিত হোন যে আপনি মোটামুটি অদলবদল করছেন না। আপনি যদি হন তবে এর আকারটি হ্রাস করুন innodb_buffer_pool_size

আমি মনে করি এই বিকল্পগুলি দিয়েও আমি ইনেনডডব দিয়ে কিছুটা দ্রুতগতি পেয়েছি:

innodb_flush_method= O_DIRECT (LINUX ONLY)
innodb_flush_log_at_commit = 0
innodb_doublewrite=0
innodb_support_xa=0
innodb_checksums=0

(শেষ তিনটি আমি বিস্তৃতভাবে পরীক্ষা করিনি - আমার মনে হয় আমি সেগুলি ইন্টারনেটগুলির পরামর্শ হিসাবে পেয়েছি)) নোট করুন যে এর innodb_flush_log_at_commit=0ফলে মাইএসকিএল ক্র্যাশ বা পাওয়ার বাইরে যাওয়ার ফলে দুর্নীতির ফলাফল হতে পারে।


গ্রেগ, সাইটে আপনাকে স্বাগতম এবং আপনার উত্তরের জন্য আপনাকে ধন্যবাদ। আপনি আপনার পরামর্শের জন্য কিছু সূত্র বা যুক্তি প্রদান করতে পারে *_block_sizeএবং myisam_repair_threads? এছাড়াও, নিশ্চিত হবেন না যে 'ইন্টারনেটদের পরামর্শ' এর ভিত্তিতে ভেরিয়েবলগুলি সুর করার জন্য আমাদের পরামর্শ দেওয়া উচিত :)
ডেরেক ডোনাই

5

আপনার যদি মূলত মাইআইএসএএম টেবিল থাকে তবে আপনার বাল্ক সন্নিবেশ বাফারটি বাড়ানো উচিত । এখানে মাইএসকিউএল ডকুমেন্টেশন বাল্ক_ইন্টার_বফলার_সাইজ সেট করার বিষয়ে যা বলেছে :

মাইআইএসএএম সংক্ষিপ্তসারের জন্য বাল্ক সন্নিবেশগুলি দ্রুত তৈরি করতে একটি বিশেষ বৃক্ষের মতো ক্যাশে ব্যবহার করে ... অমানবিকতায় ডেটা যুক্ত করার সময় নির্বাচন করুন, নির্বাচন করুন ... ভ্যালু (...), (...), ... এবং লোড ডেটা ইনফিল করুন টেবিল। এই পরিবর্তনশীলটি প্রতি থ্রেডে ক্যাশে গাছের আকার সীমাবদ্ধ করে। এটি 0 তে সেট করা এই অপ্টিমাইজেশনটিকে অক্ষম করে। ডিফল্ট মান 8MB।

আপনার দুটি জিনিস করতে হবে

1) এটি /etc/my.cnf এ যুক্ত করুন

[mysqld]
bulk_insert_buffer_size=512M

2) এর জন্য বিশ্ব মান নির্ধারণ করুন

SET GLOBAL bulk_insert_buffer_size = 1024 * 1024 * 512;

যদি আপনার কাছে বিশ্বব্যাপী বাল্ক_সাইন্ট_বাফলার_সাইজ সেট করার অধিকার না থাকে, তবে এটি করুন

service mysql restart

অবশ্যই, এটি InnoDB এর জন্য নয়।

অন্য একটি কোণ থেকে, সারণীগুলি InnoDB বা মাইআইএসএএম কিনা, সূচীগুলি যদি টেবিলের চেয়ে বড় হয় তবে আপনার অনেকগুলি সূচক থাকতে পারে। আমি সাধারণত অনুমান করি যে মাইএসএএমএসএলপ্ল্যাম্প তৈরি করতে যতক্ষণ সময় লাগবে ততক্ষণে মাইআইএসএএম মাইএসকিএলডাম্পের পুনরায় লোড হওয়া উচিত। আমি আরও অনুমান করেছি যে মাইএসকিএলডাম্প তৈরি করতে যতক্ষণ ইনোএনডিবি মাইএসকিলডাম্প পুনরায় লোড করা উচিত should

যদি আপনি কোনও মাইএসকিলডাম্প পুনরায় লোড করার জন্য 4: 1 অনুপাত অতিক্রম করে থাকেন তবে আপনার অবশ্যই দুটি সমস্যার একটি রয়েছে:

  • অনেকগুলি সূচী
  • বৃহত্তর কলামগুলির কারণে সূচকগুলি খুব বড় large

আপনি এটি দিয়ে স্টোরেজ ইঞ্জিন দ্বারা আপনার ডেটার আকার মাপতে পারবেন:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size" FROM
(SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM
information_schema.tables WHERE table_schema NOT IN
('mysql','information_schema','performance_schema') AND
engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

সূচীগুলি ডেটার মতো প্রায় বড় বা আরও বড় কিনা তা দেখুন

আপনি বাইনারি লগিংকে এই জাতীয়করণ নিষ্ক্রিয় করতেও বিবেচনা করতে পারেন:

echo "SET SQL_LOG_BIN=0;" > footable.sql
mysqldump --databases foo >> footable.sql

স্ক্রিপ্টটি পুনরায় লোড করার আগে


আমি জানি না আপনি আমার দিনটি কতবার বাঁচিয়েছেন তবে এটি অনেকটা নিশ্চিত হয়ে গেছে
দিমিত্রি ডিবি

2

আপনি যদি ফাইল সিস্টেমটি পুরোপুরি বাইপাস করেন এবং মাইএসকিএলডাম্পের আউটপুটটিকে সরাসরি একটি মাইএসকিউএল প্রক্রিয়াতে পাইপ করেন তবে আপনার লক্ষণীয় পারফরম্যান্সের উন্নতি দেখতে হবে। আপনি যে ডিস্ক ড্রাইভটি ব্যবহার করছেন তার উপর কতটা চূড়ান্তভাবে নির্ভর করে তবে একা এই কারণেই ডাটাবেসের আকার নির্বিশেষে আমি খুব কমই আর ডাম্প ফাইল ব্যবহার করি।

mysqldump -uxxx -pxxx -hxxx --single-transaction --routines --databases dbname | mysql -uyyy -pyyy -hyyy

1

আমার অভিজ্ঞতা অনুসারে, হার্ড ড্রাইভই বাধা। স্পিনিং ডিস্ক ভুলে যান এসএসডি আরও ভাল, তবে এখন পর্যন্ত সবচেয়ে ভাল হ'ল এটি র‌্যামে সম্পাদন করা - যদি আপনার কাছে অল্প সময়ের জন্য পুরো ডাটাবেসটি ধারণ করার পর্যাপ্ত পরিমাণ থাকে। মোটামুটিভাবে:

  1. বন্ধ করুন mysqld
  2. / var / lib / mysql এর বিদ্যমান সামগ্রীগুলি সরিয়ে ফেলুন
  3. একটি ফাঁকা / var / lib / mysql dir তৈরি করুন
  4. মাউন্ট -t tmpfs -o আকার = 32g tmpfs / var / lib / mysql (আকার সামঞ্জস্য করুন)
  5. একটি খালি ডিবি তৈরি করুন (উদাঃ mysql_install_db, বা পূর্ববর্তী বিষয়বস্তু পুনরুদ্ধার করুন)
  6. mysqld শুরু করুন
  7. আমদানি
  8. বন্ধ করুন mysqld
  9. কপি / var / lib / mysql মাইএসকিএল 2 এ
  10. umount mysql; rmdir mysql
  11. mysql2 থেকে mysql এ সরান
  12. MySQL শুরু করুন, খুশি হোন

আমার জন্য, 35 10G (/ var / lib / mysql খরচ করে G 20G) প্রায় 35 মিনিটে (মাইডাম্পার / মাইলোডার), 45 মিনিট (mysqldump --tab / mysqlimport), 50 মিনিট (mysqldump / mysql) এ আমদানি করা যায় me , একটি 2x6- কোর 3.2GHz Xeon এ।

আপনার যদি একটি একক মেশিনে পর্যাপ্ত র‌্যাম না থাকে তবে দ্রুত নেটওয়ার্কের সাথে একে অপরের পাশে বেশ কয়েকটি কম্পিউটার থাকে, তবে তাদের র‌্যামগুলি এনবিডি (নেটওয়ার্ক ব্লক ডিভাইস) এর সাথে যুক্ত হতে পারে কিনা তা আকর্ষণীয় হবে। অথবা, ইনোডাব_ফিল_পিটার_সামগ্রী সহ, আপনি সম্ভবত প্রতিটি টেবিলের জন্য উপরের প্রক্রিয়াটি পুনরাবৃত্তি করতে পারেন।


কৌতূহলের বাইরে আমি 2 জিবি ডাটাবেসের জন্য এসএসডি (যারা আগ্রহী তাদের জন্য এসএসডিএসসি 2 বিবি 48) এর সাথে এটি তুলনা করার জন্য র‍্যামে মাইএসকিএল ডেটাডির সংরক্ষণ করার চেষ্টা করেছি। ফলাফলগুলি স্বতন্ত্র ছিল, উভয়ই 207-209 সেকেন্ড সময় নিয়েছিল। এই বিষয়ে আপনাকে বিবেচনা করে যে আপনাকে মাইএসকিএল শুরু / বন্ধ করতে হবে এবং ডিরেক্টরিগুলি অনুলিপি করতে হবে, এসএসডি এর পরিবর্তে একটি র‌্যাম ডিস্ক ব্যবহার করা আমার ক্ষেত্রে অনেক ধীর ছিল
শোকার

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