Commit graph

192663 commits

Author SHA1 Message Date
Kristian Nielsen
de0324c146 MDEV-29402: Test sequence binlog.binlog_mdev717 binlog.binlog_mysqlbinlog_raw_flush fails
Reset the GTID sequence at the start of test so earlier run tests does not
influence the expected GTID sequence.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-15 13:09:03 +01:00
Kristian Nielsen
64a743fc81 MDEV-16951: binlog_encryption.rpl_checksum failed in buildbot with wrong result
Wait for the binlog checkpoint event to fix non-determinism in the testcase.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-15 11:40:05 +01:00
Kristian Nielsen
73a38b68dc MDEV-11018: rpl.rpl_mariadb_slave_capability fails sporadically in buildbot
The test was missing a wait_for_binlog_checkpoint.inc, making it non-deterministic

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-14 17:12:59 +01:00
Dmitry Shulga
93bdb6db4d MDEV-32733: Two JSON related tests running in PS mode fail on server built with -DWITH_PROTECT_STATEMENT_MEMROOT=YES
The tests main.func_json and json.json_no_table fail on server built with
the option -DWITH_PROTECT_STATEMENT_MEMROOT=YES by the reason that a memory
is allocated on the statement's memory root on the second execution of
a query that uses the function json_contains_path().

The reason that a memory is allocated on second execution of a prepared
statement that ivokes the function json_contains_path() is that a memory
allocated on every call of the method Item_json_str_multipath::fix_fields

To fix the issue, memory allocation should be done only once on first
call of the method Item_json_str_multipath::fix_fields. Simmilar issue
take place inside the method Item_func_json_contains_path::fix_fields.
Both methods are modified to make memory allocation only once on its
first execution and later re-use the allocated memory.

Before this patch the memory referenced by the pointers stored in the array
tmp_paths were released by the method Item_func_json_contains_path::cleanup
that is called on finishing execution of a prepared statement. Now that
memory allocation performed inside the method Item_json_str_multipath::fix_fields
is done only once, the item clean up has degenerate form and can be
delegated to the cleanup() method of the base class and memory deallocation
can be performed in the destructor.
2023-11-14 17:15:07 +07:00
Daniel Black
5b9a7871ca MDEV-32776 plugin disks getmntinfo64 deprecated on macOS
The getmntinfo64 interface is deprected in MacOSX12.1.sdk.

Using getmntinfo instead.

Thanks heyingquay for reporting the bug and testing the fix.
2023-11-14 19:38:06 +11:00
Oleksandr Byelkin
0f4df26bec Merge branch '10.4' into mariadb-10.4.32 2023-11-14 08:14:44 +01:00
Daniel Bartholomew
be55051b6b
bump the VERSION 2023-11-13 13:19:39 -05:00
Marko Mäkelä
561093701b MDEV-29180 fixup: 32-bit tests
This fixes up commit 01031f43d8
2023-11-13 09:27:01 +02:00
Oleg Smirnov
28cdbab163 MDEV-29681 Server crashes when optimizing SQL with ORDER BY
When parsing statements like (SELECT .. FROM ..) ORDER BY <expr>,
there is a step LEX::add_tail_to_query_expression_body_ext_parens()
which calls LEX::wrap_unit_into_derived(). After that the statement
looks like SELECT * FROM (SELECT .. FROM ..), and parser's
Lex_order_limit_lock structure (ORDER BY <expr>) is assigned to
the new SELECT. But what is missing here is that Items in
Lex_order_limit_lock are left with their original name resolution
contexts, and fix_fields() later resolves the names incorrectly.

For example, when processing
  (SELECT * FROM t1 JOIN t2 ON a=b) ORDER BY a
Item_field 'a' in the ORDER BY clause is left with the name resolution
context of the derived table (first_name_resolution_table='t1'), so
it is resolved to 't1.a', which is incorrect.
After LEX::wrap_unit_into_derived() the statement looks like
  SELECT * FROM (SELECT * FROM t1 JOIN t2 ON a=b) AS '__2' ORDER BY a,
and the name resolution context for Item_field 'a' in the ORDER BY
must be set to the wrapping SELECT's one.

This commit fixes the issue by changing context for Items in
Lex_order_limit_lock after LEX::wrap_unit_into_derived().
2023-11-10 21:05:54 +07:00
Aleksey Midenkov
f7552313d4 MDEV-29932 Invalid expr in cleanup_session_expr() upon INSERT DELAYED
There are two TABLE objects in each thread: first one is created in
delayed thread by Delayed_insert::open_and_lock_table(), second one is
created in connection thread by Delayed_insert::get_local_table(). It
is copied from the delayed thread table.

When the second table is copied copy-assignment operator copies
vcol_refix_list which is already filled with an item from delayed
thread. Then get_local_table() adds its own item. Thus both tables
contains the same list with two items which is wrong. Then connection
thread finishes and its item freed. Then delayed thread tries to
access it in vcol_cleanup_expr().

The fix just clears vcol_refix_list in the copied table.

Another problem is that copied table contains the same mem_root, any
allocations on it will be invalid if the original table is freed (and
that is indeterministic as it is done in another thread). Since copied
table is allocated in connection THD and lives not longer than
thd->mem_root we may assign its mem_root from thd->mem_root.

Third, it doesn't make sense to do open_and_lock_tables() on NULL
pointer.
2023-11-10 15:46:15 +03:00
Aleksey Midenkov
56e479107c MDEV-28127 EXCHANGE PARTITION with non-matching vcol expression segfault
mysql_compare_tables() treated all columns non-virtual. Now it
properly checks if the columns are virtual and matches expressions.
2023-11-10 15:46:15 +03:00
Aleksey Midenkov
ebb6f57568 MDEV-23294 Segfault or assertion upon MyISAM repair
When computing vcol expression some items use current_thd and that was
not set in MyISAM repair thread. Since all the repair threads belong
to one connection and items should not write into THD we can utilize
table THD for that.
2023-11-10 15:46:15 +03:00
Aleksey Midenkov
74883f5e2f MDEV-32082 Server crash in find_field_in_table
Attempt to resolve FOR SYSTEM_TIME expression as field for derived
table is done before derived table is fully prepared, so we fail on
assertion that table_list->table is missing.

Actually Vers_history_point::resolve_unit() is done under the call of
mysql_derived_prepare() itself (sql_derived.cc:824) and the table is
assigned later at 867.

The fix disables unit resolution for field type in FOR SYSTEM_TIME
expression as it does a little sense in any case: making historical
queries based on variable field values produces the result of multiple
time points.

fix_fields_if_needed() in resolve_units() was introduced by 46be31982a
2023-11-10 15:46:15 +03:00
Aleksey Midenkov
e53e7cd134 MDEV-20545 Assertion col.vers_sys_end() in dict_index_t::vers_history_row
Index values for row_start/row_end was wrongly calculated for inplace
ALTER for some layout of virtual fields.

Possible impact

  1. history row is not detected upon build clustered index for
     inplace ALTER which may lead to duplicate key errors on
     auto-increment and FTS index add.
  2. foreign key constraint may falsely fail.
  3. after inplace ALTER before server restart trx-based system
     versioning can cause server crash or incorrect data written upon
     UPDATE.
2023-11-10 15:46:14 +03:00
Alexander Barkov
1710b6454b MDEV-26743 InnoDB: CHAR+nopad does not work well
The patch for "MDEV-25440: Indexed CHAR ... broken with NO_PAD collations"
fixed these scenarios from MDEV-26743:
- Basic latin letter vs equal accented letter
- Two letters vs equal (but space padded) expansion

However, this scenario was still broken:
- Basic latin letter (but followed by an ignorable character)
  vs equal accented letter

Fix:
When processing for a NOPAD collation a string with trailing ignorable
characters, like:
  '<non-ignorable><ignorable><ignorable>'

the string gets virtually converted to:
  '<non-ignorable><ignorable><ignorable><space><space><space>...'

After the fix the code works differently in these two cases:
1. <space> fits into the "nchars" limit
2. <space> does not fit into the "nchars" limit

Details:

1. If "nchars" is large enough (4+ in this example),
   return weights as follows:

  '[weight-for-non-ignorable, 1 char] [weight-for-space-character, 3 chars]'

  i.e. the weight for the virtual trailing space character now indicates
  that it corresponds to total 3 characters:
  - two ignorable characters
  - one virtual trailing space character

2. If "nchars" is small (3), then the virtual trailing space character
   does not fit into the "nchar" limit, so return 0x00 as weight, e.g.:

  '[weight-for-non-ignorable, 1 char] [0x00, 2 chars]'

Adding corresponding MTR tests and unit tests.
2023-11-10 06:17:23 +04:00
Andrei
d6872f9cbb MDEV-32365: post-fixes to rpl_semi_sync_slave_reply_fail 2023-11-09 14:36:46 +02:00
Alexander Barkov
62d80652be MDEV-29110 mariabackup has wrong or missing plugin-dir default?
Problem:

The file backup-my.cnf from the backup directory was loaded by
"mariabackup --prepare" only in case of the explicit --target-dir given.
It was not loaded from the default directory ./xtrabackup_backupfiles/
in case if the explicit --target-dir was missing.

In other words, it worked as follows:

1. When started as "mariabackup --prepare --target-dir=DIR", mariabackup:
  a. loads defaults from "DIR/backup-my.cnf"
  b. processes data files in the specified directory DIR

2. When started as "mariabackup --prepare", mariabackup:
  a. does not load defaults from "./xtrabackup_backupfiles/backup-my.cnf"
  b. processes data files in the default directory "./xtrabackup_backupfiles/"

This patch fixes the second scenario, so it works as follows:

2. When started as "mariabackup --prepare", mariabackup:
  a. loads defaults from "./xtrabackup_backupfiles/backup-my.cnf"
  b. processes data files in the default directory "./xtrabackup_backupfiles/"

This change fixes (among others) the problem with the
"Can't open shared library '/file_key_management.so'" error
reported when "mariabackup --prepare" is used without --target-dir
in combinaton with the encryption plugin.
2023-11-09 12:37:06 +04:00
Alexander Barkov
2b6d241ee4 MDEV-27744 LPAD in vcol created in ORACLE mode makes table corrupted in non-ORACLE
The crash happened with an indexed virtual column whose
value is evaluated using a function that has a different meaning
in sql_mode='' vs sql_mode=ORACLE:

- DECODE()
- LTRIM()
- RTRIM()
- LPAD()
- RPAD()
- REPLACE()
- SUBSTR()

For example:

CREATE TABLE t1 (
  b VARCHAR(1),
  g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,
  KEY g(g)
);

So far we had replacement XXX_ORACLE() functions for all mentioned function,
e.g. SUBSTR_ORACLE() for SUBSTR(). So it was possible to correctly re-parse
SUBSTR_ORACLE() even in sql_mode=''.

But it was not possible to re-parse the MariaDB version of SUBSTR()
after switching to sql_mode=ORACLE. It was erroneously mis-interpreted
as SUBSTR_ORACLE().

As a result, this combination worked fine:

SET sql_mode=ORACLE;
CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...;
INSERT ...
FLUSH TABLES;
SET sql_mode='';
INSERT ...

But the other way around it crashed:

SET sql_mode='';
CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...;
INSERT ...
FLUSH TABLES;
SET sql_mode=ORACLE;
INSERT ...

At CREATE time, SUBSTR was instantiated as Item_func_substr and printed
in the FRM file as substr(). At re-open time with sql_mode=ORACLE, "substr()"
was erroneously instantiated as Item_func_substr_oracle.

Fix:

The fix proposes a symmetric solution. It provides a way to re-parse reliably
all sql_mode dependent functions to their original CREATE TABLE time meaning,
no matter what the open-time sql_mode is.

We take advantage of the same idea we previously used to resolve sql_mode
dependent data types.

Now all sql_mode dependent functions are printed by SHOW using a schema
qualifier when the current sql_mode differs from the function sql_mode:

SET sql_mode='';
CREATE TABLE t1 ... SUBSTR(a,b,c) ..;
SET sql_mode=ORACLE;
SHOW CREATE TABLE t1;   ->   mariadb_schema.substr(a,b,c)

SET sql_mode=ORACLE;
CREATE TABLE t2 ... SUBSTR(a,b,c) ..;
SET sql_mode='';
SHOW CREATE TABLE t1;   ->   oracle_schema.substr(a,b,c)

Old replacement names like substr_oracle() are still understood for
backward compatibility and used in FRM files (for downgrade compatibility),
but they are not printed by SHOW any more.
2023-11-08 15:01:20 +04:00
Marko Mäkelä
228b7e4db5 MDEV-13626 Merge InnoDB test cases from MySQL 5.7
This imports and adapts a number of MySQL 5.7 test cases that are
applicable to MariaDB.

Some tests for old bug fixes are not that relevant because the code
has been refactored since then (especially starting with
MariaDB Server 10.6), and the tests would not reproduce the
original bug if the fix was reverted.

In the test innodb_fts.opt, there are many duplicate MATCH ranks, which
would make the results nondeterministic. The test was stabilized by
changing some LIMIT clauses or by adding sorted_result in those cases
where the purpose of a test was to show that no sorting took place
in the server.

In the test innodb_fts.phrase, MySQL 5.7 would generate FTS_DOC_ID that
are 1 larger than in MariaDB. In innodb_fts.index_table the difference is 2.
This is because in MariaDB, fts_get_next_doc_id() post-increments
cache->next_doc_id, while MySQL 5.7 pre-increments it.

Reviewed by: Thirunarayanan Balathandayuthapani
2023-11-08 12:17:14 +02:00
Monty
2447172afb Ensure that process "State" is properly cleaned after query execution
In some cases "SHOW PROCESSLIST" could show "Reset for next command"
as State, even if the previous query had finished properly.

Fixed by clearing State after end of command and also setting the State
for the "Connect" command.

Other things:
- Changed usage of 'thd->set_command(COM_SLEEP)' to
  'thd->mark_connection_idle()'.
- Changed thread_state_info() to return "" instead of NULL. This is
  just a safety measurement and in line with the logic of the
  rest of the function.
2023-11-07 10:07:30 +02:00
Marko Mäkelä
01623ac9ea Fix clang -Wtypedef-redefinition 2023-11-06 10:32:39 +02:00
Marko Mäkelä
f77a3868a7 MDEV-11816 fixup: Remove an orphan test file 2023-11-06 10:20:51 +02:00
Alexey Botchkov
fa81afdaa6 MDEV-27595 Backport SQL service, introduced by MDEV-19275.
Post-review fixes.
2023-11-05 23:35:32 +04:00
Alexey Botchkov
910a0ddd2d MDEV-27295 Backport SQL service, introduced by MDEV-19275.
necessary functions added to the SQL SERVICE.
2023-11-05 23:35:32 +04:00
Alexey Botchkov
b080cff3aa MDEV-27295 Backport SQL service, introduced by MDEV-19275.
ifdef fixed.
2023-11-05 23:35:32 +04:00
Alexey Botchkov
e2c90e36b4 Fix to quiet the compiler on Windows. 2023-11-05 23:35:32 +04:00
Alexey Botchkov
624ad863d0 MDEV-27595 Backport SQL service, introduced by MDEV-19275.
test_sql_service.test fixed.
2023-11-05 23:35:32 +04:00
Alexey Botchkov
f814325105 MDEV-27595 Backport SQL service, introduced by MDEV-19275.
Embedded-server related fixes.
2023-11-05 23:35:32 +04:00
Alexey Botchkov
3a8eb405e7 MDEV-27832 disable binary logging for SQL SERVICE.
Binary logging is now disabled for the queries run by SQL SERVICE.
The binlogging can be turned on with the 'SET SQL_LOG_BIN=On' query.

Conflicts:
	sql/sql_prepare.cc

Conflicts:
	sql/sql_prepare.cc
2023-11-05 23:35:31 +04:00
Alexey Botchkov
801b45bf4f MDEV-26890 : Crash on shutdown, with active binlog dump threads
Backported from 10.7.
   The reason for the crash was a bug in MDEV-19275, after which
   shutdown does not wait for binlog threads anymore.
2023-11-05 23:35:31 +04:00
Alexey Botchkov
f71f471ed2 MDEV-27595 Backport SQL service, introduced by MDEV-19275.
Fixes to make SQL SERVICE working.

Conflicts:
	storage/spider/spd_table.cc
2023-11-05 23:35:31 +04:00
Alexey Botchkov
1fa196a559 MDEV-27595 Backport SQL service, introduced by MDEV-19275.
The SQL SERVICE backported into the 10.4.
2023-11-05 23:35:31 +04:00
Monty
f0fe23566b Fixed some valgrind warnings from unixODBC used by CONNECT 2023-11-04 16:12:41 +02:00
Monty
e5a5573f78 rpl.rpl_invoked_features fails sporadically with "Duplicate key error"
The reason was that Event e11 was re-executed before
"ALTER EVENT e11 DISABLE" had been executed.

Fixed by increasing re-schedule time

Other things:
- Removed double accounting of 'execution_count'. It was incremented in
  top->mark_last_executed(thd) that was executed a few lines earlier.
2023-11-03 11:42:52 +02:00
Monty
7533062f17 MDEV-32518 Test failure: ./mtr --no-reorder main.log_slow_debug main.subselect
There where two errors left from the previous fix.

- subselect.test assumes that mysql.slow_log is empty. This was not
  enforced.
- subselect.test dropped a file that does not exists (for safety).
  This was fixed by ensuring we don't get a warning if the file does
  not exist.
2023-11-03 11:42:52 +02:00
Kristian Nielsen
9fa718b1a1 Fix mariabackup InnoDB recovered binlog position on server upgrade
Before MariaDB 10.3.5, the binlog position was stored in the TRX_SYS page,
while after it is stored in rollback segments. There is code to read the
legacy position from TRX_SYS to handle upgrades. The problem was if the
legacy position happens to compare larger than the position found in
rollback segments; in this case, the old TRX_SYS position would incorrectly
be preferred over the newer position from rollback segments.

Fixed by always preferring a position from rollback segments over a legacy
position.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-03 09:13:51 +01:00
Kristian Nielsen
f8f5ed2280 Revert: MDEV-22351 InnoDB may recover wrong information after RESET MASTER
This commit can cause the wrong (old) binlog position to be recovered by
mariabackup --prepare. It implements that the value of the FIL_PAGE_LSN is
compared to determine which binlog position is the last one and should be
recoved. However, it is not guaranteed that the FIL_PAGE_LSN order matches the
commit order, as is assumed by the code. This is because the page LSN could be
modified by an unrelated update of the page after the commit.

In one example, the recovery first encountered this in trx_rseg_mem_restore():

  lsn=27282754  binlog position (./master-bin.000001, 472908)

and then later:

  lsn=27282699  binlog position (./master-bin.000001, 477164)

The last one 477164 is the correct position. However, because the LSN
encountered for the first one is higher, that position is recovered instead.
This results in too old binlog position, and a newly provisioned slave will
start replicating too early and get duplicate key error or similar.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-03 09:13:51 +01:00
Kristian Nielsen
e6bd4762fe Test case for provisioning a slave with mariabackup --no-lock
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-03 09:11:51 +01:00
Kristian Nielsen
167fe6646d Restore getting InnoDB position from mariabackup --no-lock
Revert the patch for MDEV-18917, which removed this functionality.
This restores that mariabackup --prepare recovers the transactional
binlog position from the redo log, and writes it to the file
xtrabackup_binlog_pos_innodb.

This position is updated only on every InnoDB commit. This means that
if the last event in the binlog at the time of backup is a DDL or
non-transactional update, the recovered position from --no-lock will
be behind the state of the backup.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-11-03 08:55:06 +01:00
Rex
e695337448 MDEV-31995-fix short fix for memory leak introduced in MDEV-31995
list elements not correctly allocated in push_back.
2023-11-03 14:04:32 +12:00
Gulshan Kumar Prasad
29df46f3a8 MDEV-29101 mariabackup --help output should mention that --compress is deprecated
Deprecation versions taken from https://mariadb.com/kb/en/mariabackup-options/#-compress
2023-11-03 10:09:42 +11:00
Oleksandr Byelkin
d914d09f58 MDEV-25329: Assertion `allocated_status_memory != __null' failed in void PROF_MEASUREMENT::set_label(const char*, const char*, const char*, unsigned int)
Make profiler to play a bit better with memory allocators. Test suite can not be included because it lead to non free memory on shutdown (IMHO OK for memory shortage emulation)

As alternetive all this should be rewritten and ability to return errors on upper level should be added.
2023-11-02 16:46:35 +01:00
Oleksandr Byelkin
01031f43d8 MDEV-29180: Description of log_warnings incorrectly mentions "general log" 2023-11-02 16:46:34 +01:00
Marko Mäkelä
bfab4ab000 MDEV-18867 fixup: Remove DBUG injection
In commit 75e82f71f1 the code to
rename internal tables for FULLTEXT INDEX that had been
created on Microsoft Windows using incompatible names
was removed. Let us also remove the related fault injection.
2023-11-02 15:27:52 +02:00
Thirunarayanan Balathandayuthapani
b4de67da45 MDEV-32638 MariaDB crashes with foreign_key_checks=0 when changing a column and adding a foreign key at the same time
Problem:
=======
 - InnoDB fails to find the foreign key index for the newly
added foreign key relation. This is caused by commit
5f09b53bdb (MDEV-31086).

FIX:
===
In check_col_is_in_fk_indexes(), while iterating through
the newly added foreign key relationship, InnoDB should
consider that foreign key relation may not have foreign index
when foreign key check is disabled.
2023-11-02 14:33:05 +05:30
HaoZhang
f9d2fd1f3f typo fixed. HAVE_mi_uint8korr 2023-11-02 19:42:39 +11:00
Oleksandr Byelkin
df93b4f259 Fix MDEV-30820 problem found by Monty 2023-11-02 07:03:32 +01:00
Alexander Barkov
d5aff2d551 MDEV-32465 dyncol changes under view protocol
Dyncol functions like column_create() encode the
current character set inside the value.
So they cannot be used with --view-protocol.

This patch changes only --disable_view_protocol to
--disable_service_connection.
2023-11-02 07:07:55 +04:00
Igor Babaev
9e321a44ee MDEV-28615 Crash caused by multi-table UPDATE over derived with hanging CTE
This bug affected only multi-table update statements and in very rare
cases: one of the tables used at the top level of the statement must be
a derived table containg a row construct with a subquery including hanging
CTE.

Before this patch was applied the function prepare_unreferenced() of the
class With_element when invoked for the the hangin CTE did not properly
restored the value of thd->lex->context_analysis_only. As a result it
became 0 after the call of this function.
For a query affected by the bug this function is called when
JOIN::prepare() is called for the subquery with a hanging CTE. This happens
when Item_row::fix_fields() calls fix_fields() for the subquery. Setting
the value of thd->lex->context_analysis_only forces the caller function
Item_row::fix_fields() to invoke the virtual method is_null() for the
subquery that leads to execution of it. It causes an assertion failure
because the call of Item_row::fix_fields() happens during the invocation
of Multiupdate_prelocking_strategy::handle_end() that calls the function
mysql_derived_prepare() for the derived table used by the UPDATE at the
time when proper locks for the statement tables has not been acquired yet.

With this patch the value of thd->lex->context_analysis_only is restored
to CONTEXT_ANALYSIS_ONLY_DERIVED that is set in the function
mysql_multi_update_prepare().

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-11-01 10:43:30 -07:00
Brandon Nesterenko
80ea3590de MDEV-32655: rpl_semi_sync_slave_compressed_protocol.test assert_only_after is wrong
The MTR test rpl.rpl_semi_sync_slave_compressed_protocol scans the
log file to ensure there is no magic number error. It attempts to
only scan the log files of the current test; however, the variable
which controls this, , is initialized incorrectly,
and it thereby scans the entire log file, which includes output from
prior tests. This causes it to fail if a test which expects this
error runs previously on the same worker.

This patch fixes the assert_only_after so the test only scans
through its own log contents.
2023-11-01 09:10:17 -06:00