DELETE / TRUNCATE查询导致表无法访问

时间:2016-04-22 09:45:00

标签: mysql database python-2.7

我的数据库中有几(3)个表存在问题,它们根本没有响应。巧合的是,我执行DELETE和TRUNCATE查询的唯一表。数据库中的其余表格工作正常,没有任何问题。祸害'腐败'表我不能做以下任何事情:

  • 浏览PHPmyadmin或Navicat中的行/结构(损坏的表非常小)。 30秒后,错误的MySQL服务器已经消失了#39;出现。
  • 通过PHPmyadmin,Python或Navicat截断/删除表。相同的MySQL服务器已经消失了一段时间后出现错误(下面显示了2次尝试)。

    Got a MySQL error (2013: Lost connection to MySQL server during query) on the following query: drop table scrape_allocations2
    Got a MySQL error (2006: MySQL server has gone away) on the following query: drop table scrape_allocations2
    
  • 修复/检查/优化表或数据库也会永久挂起并且无效。
  • 创建数据库备份会挂起并失败。
  • 对此表执行任何操作的任何其他查询(SELECT,INSERT等)都不起作用,并且失败并出现相同的错误。

其中两个表显示间歇性问题,因此他们遇到了这个问题,但几个小时后它们又恢复正常了。一张表似乎永久处于此状态。当它在两周前首次发生时,我刚刚创建了一个具有相同作业的新表,并将旧表留在那里,但是现在两周之后新表出现了同样的问题(大约一周之后,旧表再次可访问,我丢弃了它)。

有问题的表是一个非常小的表,其中几个脚本每晚同时执行INSERT,SELECT和DELETE查询。每一行都是数据分区的分配,因此每个脚本都知道其他正在运行的脚本正在做什么,并且它们不会运行相同的分区两次。当分区由脚本完成时,它会从表中删除该行。这种方法非常有效,直到桌子以某种方式损坏。

起初我假设桌面上有某种锁,但是当我检查SHOW PROCESSLIST时,那里没有进程,SHOW OPEN TABLES没有in_use或name_locked。

由于它是一个网络托管数据库,我无法访问my.cnf文件,因此我无法在恢复模式下重启数据库。我确实有SSH登录但是在尝试编辑my.cnf文件或重新启动数据库时我被拒绝访问。此外,具有数百万行的数据库的主表非常精细,并且从未显示过任何这些问题。

这是唯一与“腐败”相互作用的代码。表,使用Python(每晚在不同服务器上同时运行5次以上):

def select_partition():
    global results

''' This is the main method, which does the following:
    1. Selects all unscraped partitions from the scrape list and checks for each partition whether
       another scraper has already allocated it.
    2. If a partition has not been allocated yet the scraper allocates the partition.
    3. Fetches all users from the scrape list belonging to the partition. Then,
       makes the HTTP request for each username. Finally, it processes the results of all requests.
    4. Deallocates the partition, repeat steps 1-3.
    5. If no partitions are left, the script stops. '''

    #1
    partitions = execute_query('SELECT partitionID FROM scrape_{0} WHERE partitionID != 0 GROUP BY partitionID'.format(TYPE))

    for partition in partitions:
    allocated = execute_query('SELECT partitionID FROM scrape_allocations2 WHERE partitionID = {0}'.format(partition[0]))

    #2
    if not allocated:
        allocation = execute_query('INSERT INTO scrape_allocations2 VALUES ({0},\'{1}\',\'{2}\')'.format(partition[0],SCRAPER_NAME,datetime.datetime.now()))
        if allocation:
            print 'Selected and allocated partition {0}. Starting to fetch the skill data now. Total time spent so far: {1} seconds'.format(partition[0],str(round(time.time() - start_time,1)))

            #3
            user_list = execute_query('SELECT userID, userName FROM scrape_{1} WHERE partitionID = {0}'.format(partition[0],TYPE))
            if user_list:
                make_requests(user_list,partition[0])
                process_results(results,build_user_dict(user_list),partition[0])

            #4
            execute_query('DELETE FROM scrape_allocations2 WHERE partitionID = {0}'.format(partition[0]),False)
            results = []
            count_fetch = 0
        return True

    #5
    print 'There are no more partitions to scrape. Stopping now.'
    return False

def execute_query(query):
    try:
        cursor.execute(query)
        db.commit()

        if query.split(' ')[0].upper() == 'SELECT':
            return cursor.fetchall()

        return True

    except MySQLdb.Error, e:
        try: print 'Got a MySQL error ({1}: {2}) on the following query: {0}'.format(query,e.args[0],e.args[1])
        except IndexError: 'Got a MySQL error ({1}: {2}) on the following query: {0}'.format(query,e)

# Main loop
while things_to_do:
    things_to_do = select_partition()

其他一些信息:

服务器版本:10.0.20-MariaDB-cll-lve - MariaDB服务器

数据库客户端版本:libmysql - mysqlnd 5.0.11-dev

0 个答案:

没有答案