【问题标题】:Exporting and importing databases导出和导入数据库
【发布时间】:2015-12-06 00:38:36
【问题描述】:

我在 iPage 上有一台服务器,我正在尝试找到一种方法来正确备份我的数据库。 iPage 让我们可以选择将所有表格一次备份到一个文件中,或者一个一个地备份到单独的文件中。但问题是,我的表中有很多行,而且很多表经常超过每个文件 10.24 MB 的导入限制,更不用说我在 iPage 上的计划的最大查询限制为每小时 150,000 个查询。这意味着,即使在那一小时内没有人访问我的站点,并且以这种方式使用了查询,如果备份文件的行数超过 150,000 行,导入将在中间中断。

我知道这个问题肯定有点含糊,但我想在这里问的是关于我应该做什么的建议,在这种情况下,以一种我可以导入我的整个文件的方式成功备份我的文件如果可能的话,数据库成功而不在中间被中断。任何其他关于备份数据库的建议也很受欢迎。

【问题讨论】:

    标签: php mysql database mysqli import


    【解决方案1】:

    我会创建增量备份。每一个很大的表,或者只是所有的表,都将包含一个名为

    的列
    dtUpdated datetime not null
    

    不要让名字暗示只是为了更新。而是在任何插入或更新时设置为 now()

    关键表中的auto_increment id 肯定有助于增量备份。我不确定我是否想在没有这样的情况下尝试它(尽管没有必要)。对于以下内容,我假设有一个 auto_increment id。

    要启动它并开始运行,请先使您的系统离线以获取任何新条目。

    使用alter table 添加任何缺失的列,例如上述两列。

    将该列dtUpdated 的所有行设置为类似

    '2015-12-06 00:00:00' 
    

    这将包括时间部分。请注意,now() 不会作为启动部分的好选择。

    将有另一个表可以小到 1 行 1 列,datetime 表示上次备份的datetime。让我们将此表称为LastBackup。在您下次备份之前,这不会改变。

    最初设置此项,如上。

    修改您的代码,以便任何插入或更新都能使dtUpdatednow() 中的条目保持最新

    Delta 备份会更小,很可能只从 dtUpdated 位于表 LastBackup 中的值之后的表中提取那些行。

    一个技巧是捕获删除。随着数据被删除,该事实被记录到表中。例如,每个被跟踪的表(如 Transactions)可能有一个对应的 DeletedTransactions 表。他们只需要两列(id、datetime)。为它们命名的删除表被带过来并重放。

    数据分别通过 Select into Outfile 和 Load Data Infile 导出和导入。这些是逗号分隔值 (CSV) 文件,不是格式为 mysqldump。原因是性能,可以看到一个轶事示例Here,尽管是一个极端情况。

    您如何处理包括命名在内的文件维护将决定您将系统恢复到时间线上的任何保存点的难易程度。

    资源:

    让您快速上手

    create table LastBackup
    (   theWhen datetime not null
    );
    
    create table Transactions
    (   id int auto_increment primary key,
        custId int not null,
        transTyp int not null,
        amount decimal(12,2) not null,
        dtUpdated datetime not null,
        key (dtUpdated)
    );
    
    create table DeletedTransactions
    (   -- a delete trigger on Transactions table does an insert here for the id
        id int not null,        -- the Transactions.id value
        dtWhen datetime not null    -- when it happened
    );
    
    
    truncate table Transactions;
    insert Transactions (custId,transTyp,amount,dtUpdated) values
    (123,1,100,'2014-07-11 14:10:00'),
    (111,2,2100,'2014-07-11 14:10:01');
    -- imagine if you had 10 million of those rows
    
    -- time for the first backup, getting everything
    truncate table LastBackup;
    insert into LastBackup (theWhen) values ('2015-12-06');
    
    select id,custId,transTyp,amount,dtUpdated
    into outfile 'c:\\dev\\transactions_20151206.txt' -- or /path/to/file/xxx.txt for linux
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\r\n' -- or '\n' for linux
    FROM transactions
    where dtUpdated<'2015-12-06';   -- this will be a range on subsequent delta backups
    

    这是刚刚导出的文本文件:

    1,123,1,100.00,"2014-07-11 14:10:00"
    2,111,2,2100.00,"2014-07-11 14:10:01"
    

    【讨论】:

    • 这似乎太复杂了,我无法理解。我不知道从哪里开始。
    • 从两张桌子开始!婴儿步。阅读 LOAD DATA INFILE 并记住 txt 文件被 Select Into Outfile 写入:P
    【解决方案2】:

    如果您的托管服务提供商支持,我建议使用 mysqldump 实用程序。您可以限制查询数量:

    mysqldump --databases X --tables Y --where="1 limit xxx"
    xxx = your query limit
    

    http://shiplu.mokadd.im/110/splitting-huge-mysql-dump-for-easy-restore/

    否则,您可以使用 select 语句简单地选择有限数量的行并根据您的导出大小限制导出它们

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-12
      • 2011-06-10
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多