Очень большой импорт MySQL с интенсивной записью

У меня есть (что я хотел бы рассмотреть) огромный набор текстовых файлов, размером около 400 ГБ, которые импортируются в базу данных MySQL (механизм InnoDB). Размер файлов.txt варьируется от 2 до 26 ГБ, и каждый файл представляет собой таблицу в базе данных. Мне дали скрипт Python, который анализирует TXT-файлы и создает операторы SQL. У меня есть машина, специально предназначенная для этой задачи, со следующими характеристиками:

  • ОС - Windows 10
  • 32 ГБ ОЗУ
  • 4TB жесткий диск
  • процессор i7 3.40 ГГц

Я хочу, чтобы этот импорт был максимально быстрым и грязным. Я изменил следующие параметры конфигурации в файле MySQL my.ini на основе вопросов о стеке O, документации MySQL и других источников:

max_allowed_packet=1073741824;

autocommit=0;

net_buffer_length=0;

foreign_key_check=0;

unique_checks=0;

innodb_buffer_pool_size=8G; (this made a big difference in speed when I increased from the default of 128M)

Существуют ли другие параметры в файле конфигурации, которые я пропустил (возможно, из-за ведения журнала или кэширования), которые заставили бы MySQL использовать значительную часть ресурсов компьютера? Может ли быть еще одно узкое место, которое я пропускаю?

(Примечание: не уверен, связано ли это - когда я запускаю импорт, mysqld Процесс раскручивается, чтобы использовать около 13-15% системной памяти, но, кажется, никогда не очищает его, когда я не позволяю сценарию Python продолжить импорт. Мне интересно, является ли это результатом работы с настройками регистрации и сброса. Заранее благодарю за любую помощь.)

(РЕДАКТИРОВАТЬ)

Вот соответствующая часть скрипта Python, которая заполняет таблицы. Похоже, что скрипт соединяет, фиксирует и закрывает соединение для каждых 50000 записей. Могу ли я удалить conn.commit() в конце функции, и пусть MySQL обрабатывает принятие? Комментарии ниже while (true) взяты из авторов сценария, и я изменил это число так, чтобы оно не превышало размер max_allowed_packet.

    conn = self.connect()

    while (True):
        #By default, we concatenate 200 inserts into a single INSERT statement.
        #a large batch size per insert improves performance, until you start hitting max_packet_size issues.
        #If you increase MySQL server's max_packet_size, you may get increased performance by increasing maxNum
        records = self.parser.nextRecords(maxNum=50000)
        if (not records):
            break

        escapedRecords = self._escapeRecords(records) #This will sanitize the records
        stringList = ["(%s)" % (", ".join(aRecord)) for aRecord in escapedRecords]

        cur = conn.cursor()
        colVals = unicode(", ".join(stringList), 'utf-8')
        exStr = exStrTemplate % (commandString, ignoreString, tableName, colNamesStr, colVals)
        #unquote NULLs
        exStr = exStr.replace("'NULL'", "NULL")
        exStr = exStr.replace("'null'", "NULL")

        try:
            cur.execute(exStr)
        except MySQLdb.Warning, e:
            LOGGER.warning(str(e))
        except MySQLdb.IntegrityError, e:
        #This is likely a primary key constraint violation; should only be hit if skipKeyViolators is False
            LOGGER.error("Error %d: %s", e.args[0], e.args[1])
        self.lastRecordIngested = self.parser.latestRecordNum
        recCheck = self._checkProgress()
        if recCheck:
            LOGGER.info("...at record %i...", recCheck)
    conn.commit()
    conn.close()

0 ответов

Другие вопросы по тегам