1. Jun 06, 2023
    • Dimitri Fontaine's avatar
      Add support for the timescaledb extension. · 3cf7f12b
      Dimitri Fontaine authored
      This extension requires specific pre and post pg_restore steps to be
      implemented, and also seems to require pgcopydb to use a superuser role to
      be able to fetch the data and use pg_dump.
      3cf7f12b
  2. Jun 05, 2023
    • Dimitri Fontaine's avatar
    • Dimitri Fontaine's avatar
      Assorted set of small fixes. (#307) · 9a5cb04f
      Dimitri Fontaine authored
      - When the filtering results in an empty list of selected tables, make
          sure we don't enter infinite loop waiting for events that won't happen.
      
        - Make sure to prepare the pgcopydb_table_size (temporary) table when
          doing the pgcopydb copy ... commands that need it.
      
        - Ensure proper memory allocation and calloc() error detection when
          printing the summary tables.
      
        - Work around what looks like a compiler bug when int errors = 0; actually
          sets the errors counter to 32759 on macOs. For that the COPY workers are
      	now always in "fail-fast" mode, we can't count the errors anymore.
      9a5cb04f
    • Shubham Dhama's avatar
      Fix file rotation issue during streaming. (#298) · 5911755f
      Shubham Dhama authored
      * Fix file rotation issue during streaming.
      
      Fixes a bug that occurs when multiple transactions have BEGIN and other
      statements in one WAL file, while their COMMITs are in the next file. The
      issue arises when pgcopydb receives the COMMIT of the first transaction,
      causing it to move to the next file. However, upon receiving the BEGIN of
      the next transaction, it incorrectly goes back to the previous file,
      resulting in an inconsistent file rotation pattern.
      
      To address this issue, this commit introduces tracking the LSN of the last
      message written to the file. With this, file rotation is skipped if the
      incoming message has an LSN less than the lastWrittenLSN, ensuring that
      writes consistently occur in the current or next file.
      
      * Rename lastWrite to lastWriteTime.
      
      * Fix missing commit_lsn for continued transaction.
      
      When a transaction is split into multiple JSON WAL files, the transformed
      BEGIN statement does not include the commit_lsn since the COMMIT statement
      appears in the next file. This poses a challenge during the apply process,
      as the commit_lsn is necessary to determine when to start applying the
      current and subsequent changes.
      
      To resolve this issue, this fix parse the commit_lsn during the apply phase
      from a transaction metadata file. This file is created during the transform
      phase as soon as the COMMIT message is processed. However, this also
      implies that the apply process must wait for the creation of this file
      before it can begin applying the changes.
      
      Fixes: #299
      5911755f
  3. Jun 02, 2023
    • Dimitri Fontaine's avatar
      Use JSON format for work-directory summary files. (#300) · cda0e347
      Dimitri Fontaine authored
      This ensures that Postgres object names are properly handled even when they
      may contain multiple lines, which is accepted, possible... and then found in
      the field.
      
      In passing, ensure that we VACUUM ANALYZE tables without indexes. It's
      almost relevant to that patch because the failure mode of multiple-lines
      table names would break our vacuum module.
      cda0e347
    • Dimitri Fontaine's avatar
      Switch from semaphores to message queue to share workload. (#305) · af554b5b
      Dimitri Fontaine authored
      Using semaphores for work-sharing isn't ideal and brings some complexity and
      inefficiencies (each worker process loops over the whole table array). Now
      that we have introduced Sys V queues, use that mechanism instead to share
      the workload between table-data COPY workers.
      
      We still need to use a semaphore to create the lockfile and donefile so that
      we can track progress, resume from interrupted operations, and discover if
      all the partitions of a single table have been processed already. That said,
      we don't have to deal with same-table concurrency using the semaphore and
      files, the queue solves that for us.
      af554b5b
    • Dimitri Fontaine's avatar
      Avoid testing with postgis_topology. (#306) · f060895b
      Dimitri Fontaine authored
      This is currently a moving target. Version 3.3.3 adds topology_id_seq as an
      Extension Configuration Table, and pgcopydb is not ready to handle a
      sequence there.
      f060895b
  4. May 30, 2023
    • Shubham Dhama's avatar
      Fix apply when file starts with non-begin/keepalive statements. (#304) · 6f615278
      Shubham Dhama authored
      This fixes the issues where we skip applying I/U/D/T/C leading to the
      warning "there is already a transaction in progress" when a txn continues
      to next file and first statement of that file is not a BEGIN or KEEPALIVE
      statement. In that case, `reachedStartPos` is never set to true and apply
      never starts.
      
      This happens because `reachedStartPos` is set to `false` everytime a new
      file is processed.
      6f615278
    • Shubham Dhama's avatar
      transform: Fix transformation to empty txn when first line is COMMIT. (#303) · ccf476f8
      Shubham Dhama authored
      During prefetching, when a transaction continues to the next file and the
      first line of the next file (which is also the only remaining statement of
      the transaction) is a COMMIT message, it is incorrectly interpreted as an
      empty transaction. This fix addresses that issue.
      ccf476f8
    • Shubham Dhama's avatar
      Fix empty xid and timestamp for continued txn COMMIT messages. (#302) · 6fc44e61
      Shubham Dhama authored
      This fixes the missing `xid` and `timestamp` for continued transactions,
      ```sql
      COMMIT; -- {"xid":0,"lsn":"6/A50001C8","timestamp":""}
      ```
      
      This timestamp is used in `pgsql_replication_origin_xact_setup` which we
      update along with `COMMIT;` statement. So it makes more sense to put
      COMMIT's `timestamp` as origin timestamp.
      
      Retaining the current update with `BEGIN` action as well. This avoids
      `timestamp` being empty for `BEGIN` SQL statement in the file when COMMIT
      spills to next SQL file.
      6fc44e61
    • Dimitri Fontaine's avatar
      At follow mode switch, skip empty transform queues. (#301) · e8b79a78
      Dimitri Fontaine authored
      Check the number of messages in the queue before entering a message receive
      loop that won't exit before reading in the STOP message. When the queue is
      empty, this turns into an infinite loop.
      e8b79a78
  5. May 25, 2023
  6. May 22, 2023
  7. May 15, 2023
  8. May 11, 2023
    • Dimitri Fontaine's avatar
      Fix how snapshot are exported when using CDC. (#279) · 19f72f6a
      Dimitri Fontaine authored
      It turns out that we can't just call pg_create_logical_replication_slot() in
      a transaction that uses a snapshot to sync the initial copy of the data with
      the change data capture. We need to use the CREATE_REPLICATION_SLOT logical
      replication command with the RESERVE_WAL true SNAPSHOT 'export' options.
      
      * Add a new test case that fails because of missing data around replication slot creation.
      
      * Implement tracking of --plugin, --origin, and --slot-name options.
      
      We already tracked --snapshot so that we can --resume and continue operating
      with the same snapshot as before, and we should really have the same
      facility for the rest of the replication based options.
      
      * In --follow mode, export the snapshot via CREATE_REPLICATION_SLOT.
      
      The previous code would set transaction snapshot to a previously exported
      snapshot and then create the logical replication slot, but that creates a
      replication gap. Postgres supports only one way to avoid that gap, which
      consists of exporting the snapshot used to create the replication slot.
      
      In passing, register the full information we get from creating the
      replication slot to file, in such a way that we can re-use that file and
      information later, including the consistent_point LSN that is associated
      with the replication slot... and the snapshot.
      
      As a result, the following commands have been removed from the CLI:
      
          pgcopydb stream create slot
          pgcopydb stream create origin
          pgcopydb stream drop slot
          pgcopydb stream drop origin
      
      The only way to create a replication slot with pgcopydb is now the command
      `pgcopydb snapshot --follow`, and the replication origin on the target must
      be created with the consistent_point LSN returned by the same command.
      
      * Fix unit tests to adjust to the new API/CLI.
      
      The creation of a replication slot is not done in the pgcopydb steam setup
      command anymore, the command pgcopydb snapshot --follow must be used now.
      
      * Fix installing default values for --plugin and --slot-name.
      
      In particular the option --plugin also is supported via the environment
      variable PGCOPYDB_OUTPUT_PLUGIN and we must refrain from overwritting the
      value we might have read from there.
      
      Then we need to adjust the tests to wait until the coproc snapshot command
      has created its snapshot and files on-disk to be able to properly read the
      values from there (snapshot, replication slot name and lsn, etc).
      19f72f6a
    • Dimitri Fontaine's avatar
    • Dimitri Fontaine's avatar
      Fix pgsql is_response_ok to accept also PGRES_COPY_BOTH. (#284) · 59ec46dd
      Dimitri Fontaine authored
      That result status comes from our implementation of a logical decoding
      client, where COPY BOTH protocol is used.
      59ec46dd
    • Dimitri Fontaine's avatar
    • Shubham Dhama's avatar
      Fix double precision out of range during COPY. (#281) · d8075076
      Shubham Dhama authored
      We have identified the root cause of the issue where double precision values were going out of range during the COPY operation. It turns out that we were missing the extra_float_digits GUC (grand unified configuration) while copying the float8 data. As a result, when extreme values like '1.7976931348623157E+308' were copied from the source, an overflow occurred.
      d8075076
  9. May 05, 2023
    • Dimitri Fontaine's avatar
      Fix the transition between replay operating modes. (#277) · dd1744fd
      Dimitri Fontaine authored
      When switching replay operating modes we want to replay all the changes that
      has been streamed locally but have not been caught-up yet. This includes
      some JSON to SQL transformation work that was missed before.
      
      To be able to receive from the transform queue after having received a
      signal to stop, we need to also reset the signals control flags, otherwise
      all we get is an early exit in queue_receive.
      dd1744fd
  10. May 02, 2023
  11. Apr 28, 2023
    • Dimitri Fontaine's avatar
      53e85804
    • Dimitri Fontaine's avatar
      Update pgcopydb sentinel's replay_lsn asynchronously. (#267) · 18ff38ab
      Dimitri Fontaine authored
      * Update pgcopydb sentinel's replay_lsn asynchronously.
      
      When in follow replay mode, the pgcopydb sentinel is updated quite
      frequently so that we can see progress being made and be reactive about when
      to implement the migration cutover.
      
      Now, we might have to consider some latency with the source database system
      where the replay_lsn is published, so rate-limiting those sentinel updates
      is important. Also, rate limiting alone might not be enough to prevent
      slowing down the replay process, so switch to using libpq async API.
      
      * Make sure to update replay_lsn before sub-process exit.
      18ff38ab
  12. Apr 27, 2023
  13. Apr 25, 2023
  14. Apr 20, 2023
    • Dimitri Fontaine's avatar
      Fix the previous commit to switch to dynamic memory for schema parts. (#260) · c3ce5f40
      Dimitri Fontaine authored
      The summary commands were also statically allocated with BUFSIZE bytes,
      which is not always enough to fit the index definitions etc. Apply same
      approach as in commit f05d75b6.
      
      Also add unit test coverage this time.
      c3ce5f40
    • Dimitri Fontaine's avatar
      Assorted streaming fixes, including skipping of empty transactions. (#257) · 0c4e4334
      Dimitri Fontaine authored
      * Assorted streaming fixes, including skipping of empty transactions.
      
      * Fix memory management of JSON buffers when parsing Logical Messages.
      
      Now that we need to keep around the previous LogicalMessageMetadata, we also
      need to keep around its JSON buffer. This means we can't re-use the pointer
      to the current context buffer, and we need to duplicate memory even when
      using wal2json and keeping the same JSON buffer as received.
      
      In passing, adjust the JSON files in the test suite according to the new
      empty transactions filtering and synthetic KEEPALIVE situation.
      
      * Atttempt to fix CI errors (exit code 141).
      
      The exit code 141 is 128 + 13, and 13 is SIGPIPE. It means that in our
      cdc-low-level test case when doing receive | transform | apply, one of the
      processes is trying to write to its output pipe when the next process has
      already exited, or at least closed its pipe input file descriptor.
      
      By ignoring SIGPIPE we ask the system to return EPIPE at write time. Let's
      now see how our code handles that.
      0c4e4334
  15. Apr 17, 2023
  16. Apr 14, 2023
    • Dimitri Fontaine's avatar
      Use dynamic memory for variable length schema parts. (#249) · f05d75b6
      Dimitri Fontaine authored
      Rather than using a static BUFSIZE string buffer we call calloc() to
      allocate memory dynamically for index columns, index definitions, constraint
      definition, and collation descriptions.
      
      The allocated memory is used throughout the pgcopydb program execution, and
      at the moment the memory is not de-allocated by a call to free(). Instead,
      we rely on the OS to take care of that for us when exiting pgcopydb.
      f05d75b6
    • Dimitri Fontaine's avatar
      Fix special characters in SQL queries. (#248) · 04ebb02b
      Dimitri Fontaine authored
      Instead of escaping the characters at the C code level only, issuing queries
      with actual newlines in the query text, arrange to embed escaped characters
      in the SQL query text (\n and \r).
      04ebb02b
    • Dimitri Fontaine's avatar
      Fix exclude-schema filtering to apply to pg_dump and pg_restore. (#247) · f280da00
      Dimitri Fontaine authored
      It could be that the role used to connect to the source and target databases
      lacks privileges to access some Postgres schema and/or objects within that
      schema, which means using --exclude-schema on the command line is the right
      approach.
      f280da00
    • Dimitri Fontaine's avatar
      Fix Postgres catalog queries that implement sequences filtering. (#246) · 012bd2ae
      Dimitri Fontaine authored
      We need to find sequences that are associated with table columns either as
      default values (through pg_depend entry between the sequence and pg_attrdef)
      or as an identity column (through a pg_depend entry between the sequence and
      the table column directly).
      
      Also, when a sequence is filtered-out from our pg_restore activity, then we
      need to also filter-out the archive TOC entry for the default value that
      uses the sequence, in addition to filtering out the table and the sequence
      themselves.
      
        ALTER TABLE ONLY public.bar ALTER COLUMN id SET DEFAULT nextval(...)
      
      Otherwise we get ERROR: relation does not exist in pg_restore.
      012bd2ae
    • Dimitri Fontaine's avatar
      187a89fc
  17. Apr 13, 2023
  18. Apr 07, 2023