Sequoia изнутри #3

Август 27th, 2009 по SadKo Оставить ответ »

Пролог

В предыдущем посте я описал, на какие грабли пришлось наступить, чтобы заставить Sequoia создавать таблицы в RecoveryLog и запускать backends. Тем не менее, сама работа контроллера по-прежнему оставалась некорректной, и, как выяснилось, без правки исходников решить проблему никак не получалось.

Ковыряем исходники

Исходники Sequoia точно так же, как дистрибутив и документация, доступны на официальном сайте. После разархивации объём исходников меня разочаровал, я ожидал от подобной супер-системы большего числа файлов. Но не в количестве файлов суть.
Ещё раз поглядев на генерируемое исключение, я дополз до проблемного кода в файле src/org/continuent/sequoia/controller/recoverylog/events/LogRequestEvent.java. Вот он:

  public void execute(LoggerThread loggerThread,
      RecoveryLogConnectionManager manager)
  {

    Trace logger = loggerThread.getLogger();
    try
    {
      if (logger.isDebugEnabled())

        logger.debug(Translate.get("recovery.jdbc.loggerthread.log.info",
            logEntry.getLogId()));

      PreparedStatement pstmt = manager.getLogPreparedStatement();
      pstmt.setLong(RecoveryLog.COLUMN_INDEX_LOG_ID, logEntry.getLogId());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_VLOGIN, logEntry.getLogin());
      pstmt.setString(RecoveryLog.COLUMN_INDEX_SQL, logEntry.getQuery());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_SQL_PARAMS, logEntry
          .getQueryParams());
      pstmt.setString(RecoveryLog.COLUMN_INDEX_AUTO_CONN_TRAN, logEntry
          .getAutoConnTrans());

      pstmt.setLong(RecoveryLog.COLUMN_INDEX_TRANSACTION_ID, logEntry.getTid());
      pstmt.setLong(RecoveryLog.COLUMN_INDEX_REQUEST_ID, logEntry
          .getRequestId());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_EXEC_STATUS, logEntry
          .getExecutionStatus());
      pstmt.setLong(RecoveryLog.COLUMN_INDEX_EXEC_TIME, logEntry
          .getExecutionTimeInMs());

      pstmt.setLong(RecoveryLog.COLUMN_INDEX_UPDATE_COUNT, logEntry
          .getUpdateCountResult());

      if (logger.isDebugEnabled())

        logger.debug(pstmt.toString());
      try
      {
        pstmt.setEscapeProcessing(logEntry.getEscapeProcessing());

      }
      catch (Exception ignore)
      {
      }
      // Здесь бросается исключение:

      int updatedRows = pstmt.executeUpdate();
      if ((updatedRows != 1) && logger.isWarnEnabled())

        logger
            .warn("Recovery log did not update a single entry while executing: "
                + pstmt.toString());
    }

    catch (SQLException e)
    {
      manager.invalidate();
      if ("T".equals(logEntry.getAutoConnTrans()))

        logger.error(Translate.get(
            "recovery.jdbc.loggerthread.log.failed.transaction", new String[]{

                logEntry.getQuery(), String.valueOf(logEntry.getTid())}), e);

      else
        logger.error(Translate.get("recovery.jdbc.loggerthread.log.failed",
            logEntry.getQuery()), e);

      // Push object back in the queue, it needs to be logged again
      loggerThread.putBackAtHeadOfQueue(this, e);
    }

  }

От этого кода я и стал плясать, в результате чего всё-таки смог найти место, где можно выплюнуть создаваемое SQL-выражение. Дело осталось за небольшим — скомпилить исходники.

Сборка Sequoia

Сборка, в принципе, несложна и выполняется через Ant. Но предварительно следовало сконфигурировать файл build.properties, в котором я прописал версию используемой JDK — 1.5:

javac.target = 1.5
javac.source = 1.5

После этого, немного поизучав build.xml, я запустил в shell следующую команду:

ant clean && ant jar

Исходники собрались (правда, с ворнингами, ARGH!!!), и у меня на руках уже были новые JAR, которые я и подпихнул взамен штатных.

Патчинг

После перезапуска контроллера пропатченный код выплюнул в лог SQL-выражения, используемые для вставки/обновления данных RecoveryLog:

2009-08-26 19:17:25,368 DEBUG sequoia.controller.recoverylog Insert statement: INSERT INTO T_RECOVERY VALUES(?,?,?,?,?,?,?,?,?,?)
2009-08-26 19:17:25,372 DEBUG sequoia.controller.recoverylog Update statement: UPDATE T_RECOVERY SET exec_status=?,update_count=?,exec_time=? WHERE log_id=?

Синтаксис INSERT-выражения меня просто убил, так как в нём не учтено, что поля могут поменяться местами. Потратив час на модификацию кода, я, в конце-концов, пропатчил создаваемые SQL-выражения, а также добавил отладочную инфу к проблемной функции в файле src/org/continuent/sequoia/controller/recoverylog/events/LogRequestEvent.java:

  public void execute(LoggerThread loggerThread,
      RecoveryLogConnectionManager manager)
  {

    Trace logger = loggerThread.getLogger();
    try
    {
      if (logger.isDebugEnabled())

        logger.debug(Translate.get("recovery.jdbc.loggerthread.log.info",
            logEntry.getLogId()));

      PreparedStatement pstmt = manager.getLogPreparedStatement();

      pstmt.setLong(RecoveryLog.COLUMN_INDEX_LOG_ID, logEntry.getLogId());

      if (logger.isDebugEnabled())
        logger.debug("logID = " + logEntry.getLogId());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_VLOGIN, logEntry.getLogin());
      if (logger.isDebugEnabled())

        logger.debug("login = " + logEntry.getLogin());
      pstmt.setString(RecoveryLog.COLUMN_INDEX_SQL, logEntry.getQuery());

      if (logger.isDebugEnabled())
        logger.debug("query = " + logEntry.getQuery());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_SQL_PARAMS, logEntry
          .getQueryParams());
      if (logger.isDebugEnabled())

        logger.debug("queryParams = " + logEntry.getQueryParams());
      pstmt.setString(RecoveryLog.COLUMN_INDEX_AUTO_CONN_TRAN, logEntry
          .getAutoConnTrans());

      if (logger.isDebugEnabled())
        logger.debug("autoConnTrans = " + logEntry.getAutoConnTrans());

      pstmt.setLong(RecoveryLog.COLUMN_INDEX_TRANSACTION_ID, logEntry.getTid());
      if (logger.isDebugEnabled())

        logger.debug("transactionID = " + logEntry.getTid());
      pstmt.setLong(RecoveryLog.COLUMN_INDEX_REQUEST_ID, logEntry
          .getRequestId());

      if (logger.isDebugEnabled())
        logger.debug("RequestID = " + logEntry.getRequestId());

      pstmt.setString(RecoveryLog.COLUMN_INDEX_EXEC_STATUS, logEntry
          .getExecutionStatus());
      if (logger.isDebugEnabled())

        logger.debug("executionStatus = " + logEntry.getExecutionStatus());
      pstmt.setLong(RecoveryLog.COLUMN_INDEX_EXEC_TIME, logEntry
          .getExecutionTimeInMs());

      if (logger.isDebugEnabled())
        logger.debug("executionTimeMs = " + logEntry.getExecutionTimeInMs());

      pstmt.setLong(RecoveryLog.COLUMN_INDEX_UPDATE_COUNT, logEntry
          .getUpdateCountResult());
      if (logger.isDebugEnabled())

        logger.debug("updateCount = " + logEntry.getUpdateCountResult());

      if (logger.isDebugEnabled())

        logger.debug(pstmt.toString());
      try
      {
        pstmt.setEscapeProcessing(logEntry.getEscapeProcessing());

      }
      catch (Exception ignore)
      {
      }

      int updatedRows = pstmt.executeUpdate();
      if ((updatedRows != 1) && logger.isWarnEnabled())

        logger
            .warn("Recovery log did not update a single entry while executing: "
                + pstmt.toString());
    }

    catch (SQLException e)
    {
      manager.invalidate();
      if ("T".equals(logEntry.getAutoConnTrans()))

        logger.error(Translate.get(
            "recovery.jdbc.loggerthread.log.failed.transaction", new String[]{

                logEntry.getQuery(), String.valueOf(logEntry.getTid())}), e);

      else
        logger.error(Translate.get("recovery.jdbc.loggerthread.log.failed",
            logEntry.getQuery()), e);

      // Push object back in the queue, it needs to be logged again
      loggerThread.putBackAtHeadOfQueue(this, e);
    }

  }

Ряд исключений сразу исчез. Тем не менее, остались ещё проблемы, которые были исправлены только за счёт комментирования этих строчек кода:

/*      try
      {
        pstmt.setEscapeProcessing(logEntry.getEscapeProcessing());
      }
      catch (Exception ignore)

      {
      }*/

Только после этого и очередной, N-надцатой пересборки пакетов перезапускаемый контроллер перестал ругаться на вставку и выборку данных при прогонке теста. Краш тест?

Краш-тест (leightweight version)

В качестве leightweight-теста я решил воспользоваться Sequoia Console и вырубить второй backend:

CJDBC(admin) > disable oracle02
Disabling backend oracle02 with automatic checkpoint.

Прогнав тест, я убедился, что в первую базу запись была вставлена, а в отключенную — нет. При чём, содержимое Recovery Log пополнилось записями:

LOG_ID                 VLOGIN                                                           SQL_QUERY                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SQL_QUERY_PARAM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  AUTO_CONN_TRAN TRANSACTION_ID         REQUEST_ID             EXEC_STATUS EXEC_TIME              UPDATE_COUNT           
---------------------- ---------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------- ---------------------- ---------------------- ----------- ---------------------- ---------------------- 
1                      user                                                             begin                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             T              0                      0                      S           0                      -1                     
2                      user                                                             INSERT INTO Tm_First (nID, strMessage, nCode) VALUES (?, ?, ?)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       T              0                      0                      S           118                    1                      
3                      user                                                             commit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            T              0                      0                      S           0                      0                      
4                      user                                                             rollback                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          T              1                      0                      S           0                      0                      

Что ж, впечатляет! Попробуем заново поднять backend:

CJDBC(admin) > enable oracle02
Enabling backend oracle02 from its last known checkpoint

После некоторых раздумий и логописательств, контроллер-таки остановился, и я убедился, что недостающая запись во второй базе появилась. Только это никак не ура, возвращаемся к краш-тестам.

Краш-тест (hardcore version)

Что ж, этот краш-тест, как и в предыдущих случаях, заключался в блокировке пользователя и обрубании коннекций с последующим запуском теста.
Что же в результате? В RecoveryLog появилась запись о вставке, и в первый backend запись была вставлена. Я, было, обрадовался такому положению дел и разлочил пользовательскую учётку, что не вызвало никакой реакции со стороны контроллера. Последующие запуски теста не накладывали никаких отпечатков на вторую доступную базу.
Тогда я решил перезапустить backend через консоль:

CJDBC(admin) > disable oracle02
Disabling backend oracle02 with automatic checkpoint.
CJDBC(admin) > enable oracle02
Enabling backend oracle02 from its last known checkpoint
Cannot enable backend oracle02 from a known state. Resynchronize this backend by restoring a dump.

Оппаньки! Это, значит, после временной потери коннекта я должен восстанавливать базу из бэкапа? Что за бред!!!

В поисках лекарства решил заглянуть в Administration Guide, но там нашёл инфу только про дампы.

Резюме

Фу и фи. Чем больше ковыряюсь в этой софтине, тем больше убеждаюсь в её реальной непродуманности и ненадёжности. Может быть, я чего-то упускаю, но за эти четыре дня у меня уже порой лезут глаза на лоб от её выходок. Больше всего поражают танцы с бубном вокруг, казалось бы, простых вещей. В общем, завтра ещё поковыряюсь с ней, может всё-таки докопаюсь до истины.

Реклама

Добавить комментарий

Blue Captcha Image
Refresh

*