sql >> データベース >  >> RDS >> Mysql

mysqldumpはバイナリデータを確実に処理しますか?

    いいえ、バイナリブロブがある場合は常に信頼できるとは限りません。その場合は、「-hex-blob」を使用する必要があります 「正しい結果を得るためのフラグ。

    以下のコメントからの警告:

    これらの呼び出しが失敗する場合があります(別のサーバーにインポートしますが、両方ともCentos6 / MariaDB 10を実行しています):

    mysqldump --single-transaction --routines --databases myalarm -uroot -p"PASSWORD" | gzip > /FILENAME.sql.gz
    gunzip < FILENAME.sql.gz | mysql -p"PASSWORD" -uroot --comments
    

    サイレントにインポートに失敗するファイルを生成します。 「--skip-extended-insert」を追加すると、デバッグがはるかに簡単なファイルが得られます。この行は生成されますが、読み取ることができません(ただし、エクスポートまたはインポートのいずれでもエラーは報告されません):

    INSERT INTO `panels` VALUES (1003,1,257126,141,6562,1,88891,'??\\\?ŖeV???,NULL);
    

    バイナリデータの終了引用符が元のデータにないことに注意してください。

    select hex(packet_key) from panels where id=1003;
    --> DE77CF5C075CE002C596176556AAF9ED
    

    列はバイナリデータです:

    CREATE TABLE `panels` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `enabled` tinyint(1) NOT NULL DEFAULT '1',
      `serial_number` int(10) unsigned NOT NULL,
      `panel_types_id` int(11) NOT NULL,
      `all_panels_id` int(11) NOT NULL,
      `installers_id` int(11) DEFAULT NULL,
      `users_id` int(11) DEFAULT NULL,
      `packet_key` binary(16) NOT NULL,
      `user_deleted` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`id`),
      ...
    

    したがって、いいえ、mysqldumpを必ずしも信頼できないだけでなく、エラーが発生したときにエラーを報告するためにmysqldumpに依存することもできません。

    私が使用した醜い回避策は、次のようなオプションをダンプに追加することにより、2つの問題のあるテーブルを除外するmysqldumpを実行することでした。

    --ignore-table=myalarm.panels 
    

    次に、このBASHスクリプトをハックします。基本的に、NULL列が処理され、バイナリ列が次のようにUNHEX()呼び出しに変換されるINSERT値を生成するSELECTを実行します。

    (123,45678,UNHEX("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),"2014-03-17 00:00:00",NULL),
    

    必要に応じて、選択したエディターに貼り付けて試してみてください。

    echo "SET UNIQUE_CHECKS=0;SET FOREIGN_KEY_CHECKS=0;DELETE FROM panels;INSERT INTO panels VALUES " > all.sql
    mysql -uroot -p"PASSWORD" databasename -e "SELECT CONCAT('(',id,',', enabled,',', serial_number,',', panel_types_id,',', all_panels_id,',', IFNULL(CONVERT(installers_id,CHAR(20)),'NULL'),',', IFNULL(CONVERT(users_id,CHAR(20)),'NULL'), ',UNHEX(\"',HEX(packet_key),'\"),', IF(ISNULL(user_deleted),'NULL',CONCAT('\"', user_deleted,'\"')),'),') FROM panels" >> all.sql
    echo "SET UNIQUE_CHECKS=1;SET FOREIGN_KEY_CHECKS=1;" > all.sql
    

    これにより、INSERTの最後のコンマをセミコロンに変換する必要がある「all.sql」というファイルが作成され、上記のように実行できます。そのファイルは大きいため、インタラクティブなmysqlシェルとコマンドラインの両方で設定された「大きなインポートバッファ」の調整が必要でした。

    mysql ... --max_allowed_packet=1GB
    

    バグを報告したとき、最終的に「--hex-blob」フラグが指摘されました。これは、回避策と同じですが、私の側からは些細なことです。そのオプションを追加すると、blobは最後の16進数としてダンプされます。



    1. MariaDBテンポラルテーブルとは何ですか?

    2. 2つのテーブルを結合し、where句でフィルタリングします

    3. ピボットテーブルPHP/MySQL

    4. MySQLでゼロ日付'0000-00-0000:00:00'またはNULLを使用する方が良いですか?