• unknown's avatar
    - WL#3072 Maria Recovery: · 753ee49f
    unknown authored
    Recovery of state.records (the count of records which is stored into
    the header of the index file). For that, state.is_of_lsn is introduced;
    logic is explained in ma_recovery.c (look for "Recovery of the state").
    The net gain is that in case of crash, we now recover state.records,
    and it is idempotent (ma_test_recovery tests it).
    state.checksum is not recovered yet, mail sent for discussion.
    - WL#3071 Maria Checkpoint: preparation for it, by protecting
    all modifications of the state in memory or on disk with intern_lock
    (with the exception of the really-often-modified state.records,
    which is now protected with the log's lock, see ma_recovery.c
    (look for "Recovery of the state"). Also, if maria_close() sees that
    Checkpoint is looking at this table it will not my_free() the share.
    - don't compute row's checksum twice in case of UPDATE (correction
    to a bugfix I made yesterday).
    
    
    storage/maria/ha_maria.cc:
      protect state write with intern_lock (against Checkpoint)
    storage/maria/ma_blockrec.c:
      * don't reset trn->rec_lsn in _ma_unpin_all_pages(), because it
      should wait until we have corrected the allocation in the bitmap
      (as the REDO can serve to correct the allocation during Recovery);
      introducing _ma_finalize_row() for that.
      * In a changeset yesterday I moved computation of the checksum
      into write_block_record(), to fix a bug in UPDATE. Now I notice
      that maria_update() already computes the checksum, it's just that
      it puts it into info->cur_row while _ma_update_block_record()
      uses info->new_row; so, removing the checksum computation from
      write_block_record(), putting it back into allocate_and_write_block_record()
      (which is called only by INSERT and UNDO_DELETE), and copying
      cur_row->checksum into new_row->checksum in _ma_update_block_record().
    storage/maria/ma_check.c:
      new prototypes, they will take intern_lock when writing the state;
      also take intern_lock when changing share->kfile. In both cases
      this is to protect against Checkpoint reading/writing the state or reading
      kfile at the same time.
      Not updating create_rename_lsn directly at end of write_log_record_for_repair()
      as it wouldn't have intern_lock.
    storage/maria/ma_close.c:
      Checkpoint builds a list of shares (under THR_LOCK_maria), then it
      handles each such share (under intern_lock) (doing flushing etc);
      if maria_close() freed this share between the two, Checkpoint
      would see a bad pointer. To avoid this, when building the list Checkpoint
      marks each share, so that maria_close() knows it should not free it
      and Checkpoint will free it itself.
      Extending the zone covered by intern_lock to protect against
      Checkpoint reading kfile, writing state.
    storage/maria/ma_create.c:
      When we update create_rename_lsn, we also update is_of_lsn to
      the same value: it is logical, and allows us to test in maria_open()
      that the former is not bigger than the latter (the contrary is a sign
      of index header corruption, or severe logging bug which hinders
      Recovery, table needs a repair).
      _ma_update_create_rename_lsn_on_disk() also writes is_of_lsn;
      it now operates under intern_lock (protect against Checkpoint),
      a shortcut function is available for cases where acquiring
      intern_lock is not needed (table's creation or first open).
    storage/maria/ma_delete.c:
      if table is transactional, "records" is already decremented
      when logging UNDO_ROW_DELETE.
    storage/maria/ma_delete_all.c:
      comments
    storage/maria/ma_extra.c:
      Protect modifications of the state, in memory and/or on disk,
      with intern_lock, against a concurrent Checkpoint.
      When state goes to disk, update it's is_of_lsn (by calling
      the new _ma_state_info_write()).
      In HA_EXTRA_FORCE_REOPEN, don't set share->changed to 0 (undoing
      a change I made a few days ago) and ASK_MONTY
    storage/maria/ma_locking.c:
      no real code change here.
    storage/maria/ma_loghandler.c:
      Log-write-hooks for updating "state.records" under log's mutex
      when writing/updating/deleting a row or deleting all rows.
    storage/maria/ma_loghandler_lsn.h:
      merge (make LSN_ERROR and LSN_REPAIRED_BY_MARIA_CHK different)
    storage/maria/ma_open.c:
      When opening a table verify that is_of_lsn >= create_rename_lsn; if
      false the header must be corrupted.
      _ma_state_info_write() is split in two: _ma_state_info_write_sub()
      which is the old _ma_state_info_write(), and _ma_state_info_write()
      which additionally takes intern_lock if requested (to protect
      against Checkpoint) and updates is_of_lsn.
      _ma_open_keyfile() should change kfile.file under intern_lock
      to protect Checkpoint from reading a wrong kfile.file.
    storage/maria/ma_recovery.c:
      Recovery of state.records: when the REDO phase sees UNDO_ROW_INSERT
      which has a LSN > state.is_of_lsn it increments state.records.
      Same for UNDO_ROW_DELETE and UNDO_ROW_PURGE.
      When closing a table during Recovery, we know its state is at least
      as new as the current log record we are looking at, so increase
      is_of_lsn to the LSN of the current log record.
    storage/maria/ma_rename.c:
      update for new behaviour of _ma_update_create_rename_lsn_on_disk().
    storage/maria/ma_test1.c:
      update to new prototype
    storage/maria/ma_test2.c:
      update to new prototype (actually prototype was changed days ago,
      but compiler does not complain about the extra argument??)
    storage/maria/ma_test_recovery.expected:
      new result file of ma_test_recovery. Improvements: record
      count read from index's header is now always correct.
    storage/maria/ma_test_recovery:
      "rm" fails if file does not exist. Redirect stderr of script.
    storage/maria/ma_write.c:
      if table is transactional, "records" is already incremented when
      logging UNDO_ROW_INSERT. Comments.
    storage/maria/maria_chk.c:
      update is_of_lsn too
    storage/maria/maria_def.h:
      - MARIA_STATE_INFO::is_of_lsn which is used by Recovery. It is stored
      into the index file's header.
      - Checkpoint can now mark a table as "don't free this", and maria_close()
      can reply "ok then you will free it".
      - new functions
    storage/maria/maria_pack.c:
      update for new name
    753ee49f
maria_def.h 41.1 KB