【问题标题】:How to restore the database double encoded by mysqldump如何恢复mysqldump双重编码的数据库
【发布时间】:2011-10-01 08:35:20
【问题描述】:

我使用 mysqldump 来备份我的数据库。 我的数据库被意外破坏了,现在我想恢复它。 但是 SQL 文件是由 bug#28969 双重编码的。 http://bugs.mysql.com/bug.php?id=28969 有什么解决方案可以让我的数据返回吗? 我只有mysqldump制作的SQL文件。 谢谢。


我找回了我的数据。谢谢大家。

这样,

1.导入杂乱的数据

2. 使用 sqldump 作为 'mysqldump -h "$DB_HOST -u "$DB_USER" -p"$DB_PASSWORD" --opt --quote-names --skip-set-charset --default-character-set= latin1 "$DB_NAME" > /tmp/temp.sql'

参考

http://pastebin.com/iSwVPk1w

【问题讨论】:

  • “双 utf-8”究竟是什么意思? 2个字节重复还是别的什么?一些 4 字节序列的十六进制示例将非常有帮助。我猜你可能只需要编写一个快速脚本来扫描转储文件并更正它找到的每个 UTF-8 序列。
  • 错误报告表明这可能是旧版本的 MySQL 的问题。您使用的是最新版本吗?
  • 我相信您在这里也学到了最佳实践。始终根据“刻录系统”检查您的备份,以便在需要它们进行灾难恢复之前知道它们是好的。不要难过我们都去过那里。 :D
  • @AJ,这绝对是他(或他的服务提供商)需要做的事情,但他目前正处于灾难恢复状态。他需要找回当前损坏的数据。如果数据库仍在服务器上,他将能够更新并创建新的备份,一切顺利。
  • 谢谢大家。我找回了我的数据。通过这种方式, 1.导入杂乱的数据 2.使用 sqldump 作为 'mysqldump -h "$DB_HOST -u "$DB_USER" -p"$DB_PASSWORD" --opt --quote-names --skip-set-charset - -default-character-set=latin1 "$DB_NAME" > /tmp/temp.sql' 参考pastebin.com/iSwVPk1w

标签: mysql utf-8 mysqldump


【解决方案1】:

我找回了我的数据。谢谢大家。

这样,

1.导入杂乱的数据

2.使用sqldump作为mysqldump -h "$DB_HOST -u "$DB_USER" -p"$DB_PASSWORD" --opt --quote-names --skip-set-charset --default-character-set=latin1 "$DB_NAME" > /tmp/temp.sql

参考

#!/bin/bash -e

DB_HOST="$1"
DB_USER="$2"
DB_PASSWORD="$3"
DB_NAME="$4"


mysqldump -h "$DB_HOST -u "$DB_USER" -p"$DB_PASSWORD" --opt --quote-names \
    --skip-set-charset --default-character-set=latin1 "$DB_NAME" > /tmp/temp.sql

mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" \
    --default-character-set=utf8 "$DB_NAME" < /tmp/temp.sql

【讨论】:

    【解决方案2】:

    如果只是将 UTF-8 字节加倍或添加某些内容,我建议将一个快速的 sed/awk 命令放在一起来匹配和纠正它们。

    http://www.osnews.com/story/21004/Awk_and_Sed_One-Liners_Explained

    如果您对此不满意,可以使用任何支持正则表达式的脚本语言轻松完成相同的操作,但可能需要几分钟时间。

    【讨论】:

    • 我不确定您的回答是否有帮助。我已经尝试通过“iconv”解码,但它并没有返回我的数据。幸运的是,我刚刚找到了解决方案。感谢您的帮助。
    【解决方案3】:

    如果您的数据库包含正确的排序规则,但数据库中的完整数据是双重编码的,那么这将帮助您记住您只执行一次并备份您的数据库。

    <?php
    /**
     * DoublyEncodeCorrection.php
     *
     * NOTE: Look for 'TODO's for things you may need to configure.
     * PHP Version 5
     *
     */
    ini_set('display_errors','1');
    //error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
    // TODO: Pretend-mode -- if set to true, no SQL queries will be executed.  Instead, they will only be echo'd
    // to the console.
    $pretend = true;
    
    // TODO: Should SET and ENUM columns be processed?
    $processEnums = false;
    
    // TODO: The collation you want to convert the overall database to
    $defaultCollation = 'utf8_general_ci';
    
    // TODO Convert column collations and table defaults using this mapping
    // latin1_swedish_ci is included since that's the MySQL default
    $collationMap = array(
        'latin1_bin'        => 'utf8_bin',
        'latin1_general_ci' => 'utf8_general_ci',
        'latin1_swedish_ci' => 'utf8_general_ci'
    );
    
    $mapstring = '';
    foreach ($collationMap as $s => $t) {
        $mapstring .= "'$s',";
    }
    
    $mapstring = substr($mapstring, 0, -1); // Strip trailing comma
    //echo $mapstring;
    
    // TODO: Database information
    $dbHost = 'localhost';
    $dbName = 'tina';
    $dbUser = 'root';
    $dbPass = 'root';
    
    // Open a connection to the information_schema database
    $infoDB = mysql_connect($dbHost, $dbUser, $dbPass);
    
    mysql_select_db('information_schema', $infoDB);
    
    // Open a second connection to the target (to be converted) database
    $targetDB = mysql_connect($dbHost, $dbUser, $dbPass, true);
    mysql_select_db($dbName, $targetDB);
    
    if (!is_resource($targetDB)) {
        echo "Could not connect to db!: " . mysql_error();exit;
    }
    
    if (mysql_select_db($dbName, $targetDB) === FALSE) {
        echo "Could not select database!: " . mysql_error();exit;
    }
    
    //
    // TODO: FULLTEXT Indexes
    //
    // You may need to drop FULLTEXT indexes before the conversion -- execute the drop here.
    // eg.
    //    sqlExec($targetDB, "ALTER TABLE MyTable DROP INDEX `my_index_name`", $pretend);
    //
    // If so, you should restore the FULLTEXT index after the conversion -- search for 'TODO'
    // later in this script.
    //
    
    // Get all tables in the specified database
    $tables = sqlObjs($infoDB,
        "SELECT TABLE_NAME, TABLE_COLLATION
         FROM   TABLES
         WHERE  TABLE_SCHEMA = '$dbName'");
    
    foreach ($tables as $table) {
        $tableName      = $table->TABLE_NAME;
        $tableCollation = $table->TABLE_COLLATION;
    
        // Find all columns that aren't of the destination collation
        $cols = sqlObjs($infoDB,
            "SELECT *
             FROM   COLUMNS
             WHERE  TABLE_SCHEMA    = '$dbName'
                AND TABLE_Name      = '$tableName'
                ");
    
        $intermediateChanges = array();
        $finalChanges = array();
    
        foreach ($cols as $col) {
    
            // If this column doesn't use one of the collations we want to handle, skip it
            if (in_array($col->COLLATION_NAME, $collationMap)) {
                //echo "<pre>";print_r($col->COLUMN_NAME);exit;
               sqlExec($targetDB,"UPDATE $dbName.$tableName SET $col->COLUMN_NAME = CONVERT(CAST(CONVERT($col->COLUMN_NAME USING latin1) AS BINARY) USING utf8)") ;
            }
        }
    }
    
    
    /**
     * Executes the specified SQL
     *
     * @param object  $db      Target SQL connection
     * @param string  $sql     SQL to execute
     * @param boolean $pretend Pretend mode -- if set to true, don't execute query
     *
     * @return SQL result
     */
    function sqlExec($db, $sql, $pretend = false)
    {
        echo "$sql;\n";
    
        if ($pretend === false) {
            $res = mysql_query($sql, $db);
            //echo "<pre>";print_r($res);exit;
            $error = mysql_error($db);
            if ($error !== '') {
                print "!!! ERROR: $error\n";
            }
    
            return $res;
        }
    
        return false;
    }
    
    /**
     * Gets the SQL back as objects
     *
     * @param object $db  Target SQL connection
     * @param string $sql SQL to execute
     *
     * @return SQL objects
     */
    function sqlObjs($db, $sql)
    {
        $res = sqlExec($db, $sql);
    
        $a = array();
    
        if ($res !== false) {
            while ($obj = mysql_fetch_object($res)) {
                $a[] = $obj;
            }
        }
    
        return $a;
    }
    
    ?> 
    

    【讨论】:

      猜你喜欢
      • 2014-01-30
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 2021-10-22
      • 2019-09-08
      相关资源
      最近更新 更多