ইনোডিবি টেবিল পরিবর্তন হয়েছে কিনা তা যাচাই করার দ্রুততম উপায়


22

আমার অ্যাপ্লিকেশনটি খুব ডাটাবেস নিবিড়। বর্তমানে, আমি মাইএসকিউএল 5.5.19 চালাচ্ছি এবং মাইআইএসএএম ব্যবহার করছি তবে আমি ইনোডিবিতে স্থানান্তরিত হওয়ার প্রক্রিয়াধীন। কেবলমাত্র সমস্যাটি হ'ল চেকসাম কর্মক্ষমতা।

আমার অ্যাপ্লিকেশন CHECKSUM TABLEশিখর সময়ে প্রতি সেকেন্ডে প্রায় 500-1000 স্টেটমেন্ট দেয় , কারণ ক্লায়েন্ট জিইউআই নিয়মিত পরিবর্তনের জন্য ডাটাবেসটি পোল করে চলেছে (এটি একটি মনিটরিং সিস্টেম, তাই খুব প্রতিক্রিয়াশীল এবং দ্রুত হওয়া আবশ্যক)।

মাইআইএসএএম এর সাথে, এমন লাইভ চেকসাম রয়েছে যা টেবিল পরিবর্তনে প্রাক্কলিত এবং খুব দ্রুত। তবে ইনোডিবিতে তেমন কিছুই নেই। সুতরাং, CHECKSUM TABLEখুব ধীর।

আমি টেবিলের শেষ আপডেটের সময়টি পরীক্ষা করতে সক্ষম হয়েছি বলে আশাবাদী, দুর্ভাগ্যক্রমে, এটি InnoDB তেও পাওয়া যায় না। আমি এখন আটকে আছি, কারণ পরীক্ষাগুলি দেখিয়েছে যে অ্যাপ্লিকেশনটির পারফরম্যান্স হ্রাস পেয়েছে।

কোডের কেবলমাত্র অনেকগুলি লাইন রয়েছে যা টেবিলগুলি আপডেট করে, সুতরাং সারণী পরিবর্তনগুলিতে লগ করার জন্য অ্যাপ্লিকেশনটিতে যুক্তি প্রয়োগ করা প্রশ্নটির বাইরে।

InnoDB টেবিলগুলিতে পরিবর্তনগুলি সনাক্ত করার জন্য কোনও দ্রুত পদ্ধতি আছে?

উত্তর:


15

Mydb.mytable টেবিলের জন্য, এই কোয়েরিটি চালান:

SELECT update_time
FROM information_schema.tables
WHERE table_schema='mydb'
AND table_name='mytable';

আপনি যদি জানতে চান যে গত 5 মিনিটে কোন টেবিলগুলি পরিবর্তন হয়েছে, এটি চালান:

SELECT table_schema,table_name,update_time
FROM information_schema.tables
WHERE update_time > (NOW() - INTERVAL 5 MINUTE);

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

আপডেট ২০১১-১২-২১ 20:04 ইডিটি

আমার নিয়োগকর্তার (ডিবি / ডাব্লুউইউব হোস্টিং কোমানি) 112,000 ইনোডিবি টেবিল সহ একটি ক্লায়েন্ট রয়েছে। পিক আওয়ারের সময় INFORMATION_SCHEMA.TABLES পড়া খুব কঠিন। আমার একটি বিকল্প পরামর্শ আছে:

যদি আপনি ইনোডবি_ফিল_পিটার_সামগ্রী সক্ষম করে থাকেন এবং সমস্ত InnoDB টেবিলগুলি .ibdফাইলগুলিতে সঞ্চিত থাকে তবে সর্বশেষ আপডেটের সময়টি (মিনিট অবধি) নির্ধারণের উপায় রয়েছে।

Mydb.mytable টেবিলের জন্য, অপারেটিং সিস্টেমে নিম্নলিখিতটি করুন:

$ cd /var/lib/mysql/mydb
$ ls -l mytable.ibd | awk '{print $4,$5}'

এই টাইমস্ট্যাম্পটি ওএস থেকে। আপনি এই এক ভুল করতে পারবেন না।

আপডেট ২০১১-১২-২১ 22:04 ইডিটি [মাইএসকিএলডি] ইনোডাব_ম্যাক্স_ডার্টি_পেজ_প্যাক্ট = 0;

এটিকে my.cnf এ যুক্ত করুন, মাইএসকিএল পুনরায় চালু করুন এবং সমস্ত ইনোডিবি টেবিলগুলি বাফার পুল থেকে দ্রুত ফ্লাশ গ্রহণ করবে।

পুনরায় চালু হওয়া এড়াতে, চালান

mysql> SET GLOBAL innodb_max_dirty_pages_pct=0;

আপডেট 2013-06-27 07:15 ইডিটি

যখন কোনও ফাইলের তারিখ এবং সময় পুনরুদ্ধার করার কথা আসে, তখন ls এর --time-styleবিকল্প থাকে:

$ cd /var/lib/mysql/mydb
$ ls -l --time-style="+%s" mytable.ibd | awk '{print $6}'

আপনি UNIX_TIMESTAMP (NOW ()) এর বিপরীতে ফাইলের টাইমস্ট্যাম্প তুলনা করতে পারেন ।


আপনি কি নিশ্চিত যে আপনি ডাব্লু / আইডিবি মোডেটেট ভুল করতে পারবেন না? একটি পরিবর্তন কেবল মেমরির বাফার পুলেই থাকতে পারে এবং এখনও ডিস্কে ফ্লাশ পাওয়া যায় না।
atxdba

6
উত্তরের জন্য ধন্যবাদ, তবে আমি যেমন বলেছি, তথ্য_সেমি.টিবেলে আপডেট_টাইম ইনোডিবি টেবিলের জন্য শুভ L এছাড়াও আমি নিশ্চিত নই যে ইনডোডবি_ম্যাক্স_ডাটি_পেজ_প্যাক্ট = 0 একটি ভাল ধারণা, কারণ এটি পারফরম্যান্সের ত্যাগ করবে ... আমি ট্রিগারগুলির সাথে সমাধানের বিষয়ে ভাবছিলাম, প্রতিটি পর্যবেক্ষণ সারণীর জন্য একটি রেফারেন্স টেবিলে একটি এলোমেলো মান সন্নিবেশ করানোর জন্য, তবে তারপরে আমার কেবলমাত্র এটির জন্য টেবিলের জন্য 3 টি ট্রিগার লাগবে ...
জ্যাকেট

এছাড়াও তথ্য_সেমিটা.টিব্যাটেলগুলি থেকে নির্বাচন করা ধীরে ধীরে ধীরে ধীরে ... একটি টেবিল চেক করতে আমার প্রায় 300 মিমি লাগে। তুলনা করার জন্য লাইভ চেকসাম সক্ষম সহ কয়েক মিলিয়ন সারি মাইআইএসএএম টেবিলে একটি "চেকসাম টেবিল" করতে মিলিসেকেন্ডের চেয়ে কম সময় নিচ্ছে।
জ্যাকেট

2
ফাইল সিস্টেম চেকের জন্য +1, যতক্ষণ না বাফার ফ্লাশিং যথেষ্ট নিয়মিত হয় (প্রায় প্রতি সেকেন্ডে একবার ডিফল্ট হয়), তবে এই সময়ের স্ট্যাম্পটি বেশ সঠিক হবে, এবং বেশিরভাগ ক্ষেত্রে সম্ভবত যথেষ্ট ভাল ...
ডেভ রিক্স

1
স্থানীয় ডাটাবেসের জন্য এটি ঠিক আছে তবে আমার একাধিক দূরবর্তী দাস রয়েছে, তাই এটি কাজ করছে না ...
জ্যাকেট

3

আমি মনে করি আমি সমাধানটি খুঁজে পেয়েছি। কিছু সময়ের জন্য আমি আমার মাইএসকিউএল সার্ভারগুলি প্রতিস্থাপনের জন্য পারকোনা সার্ভারের দিকে চেয়ে ছিলাম এবং এখন আমি মনে করি এটির পক্ষে যুক্তিসঙ্গত কারণ রয়েছে।

পারকোনা সার্ভার INNODB_TABLE_STATS এর মতো অনেকগুলি নতুন INFORMATION_SCHEMA টেবিল প্রবর্তন করে, যা স্ট্যান্ডার্ড মাইএসকিউএল সার্ভারে উপলভ্য নয়। যখন তুমি কর:

SELECT rows, modified FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table'

আপনি আসল সারি গণনা এবং একটি কাউন্টার পান। অফিসিয়াল ডকুমেন্টেশন এই ক্ষেত্র সম্পর্কে নিম্নলিখিত বলেছেন:

পরিবর্তিত কলামের মান যদি "সারি / 16" বা 2000000000 ছাড়িয়ে যায়, তবে ইনডোডব_স্ট্যাটস_আউটো_আপডেট == ১. যখন আমরা এই মান দ্বারা পরিসংখ্যানের প্রাচীনতা অনুমান করতে পারি তখন পরিসংখ্যান পুনর্নির্মাণ করা হয়।

সুতরাং এই কাউন্টারটি একবারে একবারে psেকে দেয় তবে আপনি সারিগুলির সংখ্যা এবং কাউন্টারটির একটি চেকসাম তৈরি করতে পারেন এবং তারপরে সারণির প্রতিটি সংশোধন করে আপনি একটি অনন্য চেকসাম পাবেন। উদাহরণ:

SELECT MD5(CONCAT(rows,'_',modified)) AS checksum FROM information_schema.innodb_table_stats WHERE table_schema='db' AND table_name='table';

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

ইঞ্জিন এবং সার্ভার যা ব্যবহার করা হোক না কেন টেবিলগুলি চেকসামড করা যায় তা নিশ্চিত করার জন্য এটি আমি এই পিএইচপি ফাংশন নিয়ে এসেছি:

function checksum_table($input_tables){
    if(!$input_tables) return false; // Sanity check
    $tables = (is_array($input_tables)) ? $input_tables : array($input_tables); // Make $tables always an array
    $where = "";
    $checksum = "";
    $found_tables = array();
    $tables_indexed = array();
    foreach($tables as $table_name){
        $tables_indexed[$table_name] = true; // Indexed array for faster searching
        if(strstr($table_name,".")){ // If we are passing db.table_name
            $table_name_split = explode(".",$table_name);
            $where .= "(table_schema='".$table_name_split[0]."' AND table_name='".$table_name_split[1]."') OR ";
        }else{
            $where .= "(table_schema=DATABASE() AND table_name='".$table_name."') OR ";
        }
    }
    if($where != ""){ // Sanity check
        $where = substr($where,0,-4); // Remove the last "OR"
        $get_chksum = mysql_query("SELECT table_schema, table_name, rows, modified FROM information_schema.innodb_table_stats WHERE ".$where);
        while($row = mysql_fetch_assoc($get_chksum)){
            if($tables_indexed[$row[table_name]]){ // Not entirely foolproof, but saves some queries like "SELECT DATABASE()" to find out the current database
                $found_tables[$row[table_name]] = true;
            }elseif($tables_indexed[$row[table_schema].".".$row[table_name]]){
                $found_tables[$row[table_schema].".".$row[table_name]] = true;
            }
            $checksum .= "_".$row[rows]."_".$row[modified]."_";
        }
    }

    foreach($tables as $table_name){
        if(!$found_tables[$table_name]){ // Table is not found in information_schema.innodb_table_stats (Probably not InnoDB table or not using Percona Server)
            $get_chksum = mysql_query("CHECKSUM TABLE ".$table_name); // Checksuming the old-fashioned way
            $chksum = mysql_fetch_assoc($get_chksum);
            $checksum .= "_".$chksum[Checksum]."_";
        }
    }

    $checksum = sprintf("%s",crc32($checksum)); // Using crc32 because it's faster than md5(). Must be returned as string to prevent PHPs signed integer problems.

    return $checksum;
}

আপনি এটি এর মতো ব্যবহার করতে পারেন:

// checksum a signle table in the current db
$checksum = checksum_table("test_table");

// checksum a signle table in db other than the current
$checksum = checksum_table("other_db.test_table");

// checksum multiple tables at once. It's faster when using Percona server, because all tables are checksummed via one select.
$checksum = checksum_table(array("test_table, "other_db.test_table")); 

আমি আশা করি এটি একই সমস্যাযুক্ত অন্যান্য ব্যক্তির জন্য কিছুটা সমস্যা বাঁচায়।


যারা আগ্রহী তাদের জন্য আরও গল্পের বিকাশ: ফোরাম.স্পারকোনা.২
জ্যাকেট

1

আপনার মাইএসকিএল v5.6 + এ আপডেট করা উচিত সেই সংস্করণ ইনোডাব এ চেকসাম টেবিলের জন্য সমর্থনও রয়েছে। http://dev.mysql.com/doc/refman/5.6/en/checksum-table.html

অন্যটি হ'ল, আদর্শ সমাধানটি হ'ল যদি আপনার ক্লায়েন্ট নিয়মিত ফলাফলের জন্য ভোটদান না করে, তবে পরিবর্তে আপনি যেখানে নতুন এবং পরিবর্তিত ডেটা ঠেলাঠেলি করেন এবং কখন তা উপলব্ধ ছিল। এটি দ্রুততর হবে এবং সার্ভারে কম লোড হবে। আপনি যদি ওয়েব ভিত্তিক গুই ব্যবহার করছেন তবে আপনার অবশ্যই এপিই http://ape-project.org/ বা অন্যান্য অনুরূপ প্রকল্পগুলির সন্ধান করা উচিত ।


দুর্ভাগ্যক্রমে, এটি একটি পারফরম্যান্স হত্যাকারী। চেকসাম একটি করে সমস্ত সারি হ্যাশ করে তৈরি করা হয় । দস্তাবেজগুলি থেকে: "এই সারি-দ্বারা-সারি গণনাটি আপনি এক্সটেন্ডড ক্লজ, মাইআইএসএএম ব্যতীত অন্যান্য আইএনএসবি এবং অন্যান্য স্টোরেজ ইঞ্জিন সহ এবং মাইআইএসএএম টেবিলের সাথে চেকসাম = 1 ধারা দ্বারা তৈরি
করেননি

1

যদি আপনি বেশিরভাগই কোনও টেবিলের সাথে যুক্ত হন তবে আপনি আপডেটের জন্য একটি পরিমাপ হিসাবে আউটপুট ক্রিক করতে পারেন।

SELECT `AUTO_INCREMENT` FROM `information_schema`.`tables` 
WHERE `table_schema` = DATABASE() AND `table_name` = 'YOUR_TABLE';

তবে আমি মেমক্যাচে একটি কাউন্টারের মতো একটি অটসাইড উত্সকে উল্লেখ করতে পছন্দ করব যা আপনি যখনই ডাটাবেজে কিছু পরিবর্তন করবেন প্রতিবার আপনি বৃদ্ধি করবেন।


0

আপনি নিম্নলিখিতটি করার চেষ্টা করতে পারেন:

SELECT rows_changed
FROM information_schema.table_statistics
WHERE table_schema = 'mydb' AND table_name='mytable';

এটি প্রতিটি সারণী আপডেটের সাথে বাড়িয়ে এমন একটি সংখ্যা ফেরত দেয়, এটির উপর নজর রাখলে পরিবর্তন সনাক্ত করতে দেয়।

গুরুত্বপূর্ণ দ্রষ্টব্য: মান আপডেটের পরে অবিলম্বে পরিবর্তিত হয়, কমিটের পরে নয়। সুতরাং আপনি যদি পরিবর্তনগুলি অন্য কোনও লেনদেনের মধ্যে সম্পন্ন করেন যা শেষ না হয় তবে আপনি পরিবর্তনগুলি দেখতে পাবেন না।


0

এই উত্তরটির সাথে মাইএসকিএল ডাটাবেস সংস্করণ বা ধরণের কোনও সম্পর্ক নেই, আমি জানতে চেয়েছিলাম যে আপডেটের বিবৃতিগুলি পরিবর্তন করছে এবং আমার পিএইচপি কোডে এটি করার জন্য ..

  1. একটি রেকর্ড এবং একটি ক্ষেত্র সহ একটি ডামি টেবিল তৈরি করেছে যা আমি মাইএসকিএল এর বর্তমান_টাইমস্ট্যাম্পের মান পেতে জিজ্ঞাসা করব।

  2. ডেটা সারণি আপডেট হওয়ার সাথে সাথে একটি টাইমস্ট্যাম্প ক্ষেত্র যুক্ত করা হয়েছে এবং মাইএসকিএল বিকল্পটি "ওপেনডে সিউরএনT_TIMESTAMP" ব্যবহার করেছেন

  3. # 1 এবং # 2 এর সাথে তুলনা করুন

এটি সময়ের 100% কাজ করবে না তবে আমার প্রয়োগের জন্য এটি ছিল একটি সহজ এবং দুর্দান্ত সমাধান। আশা করি এটি কারও সাহায্য করবে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.