@@ -101,6 +101,7 @@ void log_t::create()
101
101
ut_ad (!checkpoint_buf);
102
102
ut_ad (!buf);
103
103
ut_ad (!flush_buf);
104
+ ut_ad (!writer);
104
105
max_buf_free= 1 ;
105
106
106
107
latch.SRW_LOCK_INIT (log_latch_key);
@@ -330,6 +331,7 @@ bool log_t::attach(log_file_t file, os_offset_t size)
330
331
331
332
ut_ad (!buf);
332
333
ut_ad (!flush_buf);
334
+ ut_ad (!writer);
333
335
#ifdef HAVE_INNODB_MMAP
334
336
if (size)
335
337
{
@@ -352,7 +354,7 @@ bool log_t::attach(log_file_t file, os_offset_t size)
352
354
# endif
353
355
buf= static_cast <byte*>(ptr);
354
356
max_buf_free= 1 ;
355
- mtr_t::finisher_update ();
357
+ writer_update ();
356
358
# ifdef HAVE_PMEM
357
359
if (is_pmem)
358
360
return true ;
@@ -395,7 +397,7 @@ bool log_t::attach(log_file_t file, os_offset_t size)
395
397
TRASH_ALLOC (buf, buf_size);
396
398
TRASH_ALLOC (flush_buf, buf_size);
397
399
max_buf_free= buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN;
398
- mtr_t::finisher_update ();
400
+ writer_update ();
399
401
memset_aligned<512 >(checkpoint_buf, 0 , write_size);
400
402
401
403
#ifdef HAVE_INNODB_MMAP
@@ -508,6 +510,8 @@ void log_t::close_file()
508
510
checkpoint_buf= nullptr ;
509
511
}
510
512
513
+ writer= nullptr ;
514
+
511
515
#ifdef HAVE_INNODB_MMAP
512
516
if (really_close)
513
517
#endif
@@ -671,6 +675,8 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept
671
675
(lsn_t {write_size - 1 } + start_lsn - first_lsn));
672
676
else if (!is_opened ())
673
677
resize_log.close ();
678
+
679
+ writer_update ();
674
680
}
675
681
resize_lsn.store (start_lsn, std::memory_order_relaxed);
676
682
status= success ? RESIZE_STARTED : RESIZE_FAILED;
@@ -721,6 +727,7 @@ void log_t::resize_abort() noexcept
721
727
resize_lsn.store (0 , std::memory_order_relaxed);
722
728
}
723
729
730
+ writer_update ();
724
731
log_resize_release ();
725
732
}
726
733
@@ -924,7 +931,6 @@ void log_t::persist(lsn_t lsn, bool holding_latch) noexcept
924
931
}
925
932
#endif
926
933
927
- ATTRIBUTE_COLD ATTRIBUTE_NOINLINE
928
934
void log_t::resize_write_buf (const byte *b, size_t length) noexcept
929
935
{
930
936
const size_t block_size_1= write_size - 1 ;
@@ -959,20 +965,24 @@ void log_t::resize_write_buf(const byte *b, size_t length) noexcept
959
965
b, offset, length) == DB_SUCCESS);
960
966
}
961
967
962
- /* * Write buf to ib_logfile0.
963
- @tparam release_latch whether to invoke latch.wr_unlock()
968
+ /* * Write buf to ib_logfile0 and possibly ib_logfile101 .
969
+ @tparam resizing whether to release latch and whether resize_in_progress()>1
964
970
@return the current log sequence number */
965
- template <bool release_latch> inline lsn_t log_t::write_buf () noexcept
971
+ template <log_t ::resizing_and_latch resizing>
972
+ inline __attribute__ ((always_inline))
973
+ lsn_t log_t::write_buf() noexcept
966
974
{
967
975
ut_ad (latch_have_wr ());
968
976
ut_ad (!is_mmap ());
969
977
ut_ad (!srv_read_only_mode);
978
+ ut_ad (resizing == RETAIN_LATCH ||
979
+ (resizing == RESIZING) == (resize_in_progress () > 1 ));
970
980
971
981
const lsn_t lsn{get_lsn (std::memory_order_relaxed)};
972
982
973
983
if (write_lsn >= lsn)
974
984
{
975
- if (release_latch )
985
+ if (resizing != RETAIN_LATCH )
976
986
latch.wr_unlock ();
977
987
ut_ad (write_lsn == lsn);
978
988
}
@@ -990,7 +1000,16 @@ template<bool release_latch> inline lsn_t log_t::write_buf() noexcept
990
1000
ut_ad (write_size_1 >= 511 );
991
1001
992
1002
const byte *const write_buf{buf};
993
- const byte *const re_write_buf{resize_buf};
1003
+ byte *const re_write_buf{resizing == NOT_RESIZING ? nullptr : resize_buf};
1004
+ ut_ad (resizing == RETAIN_LATCH ||
1005
+ (resizing == NOT_RESIZING) == !re_write_buf);
1006
+ ut_ad (!re_write_buf == !resize_flush_buf);
1007
+ if (resizing == RESIZING)
1008
+ #ifdef _MSC_VER
1009
+ __assume (re_write_buf != nullptr );
1010
+ #else
1011
+ if (!re_write_buf) __builtin_unreachable ();
1012
+ #endif
994
1013
offset&= ~lsn_t {write_size_1};
995
1014
996
1015
if (length <= write_size_1)
@@ -1002,13 +1021,14 @@ template<bool release_latch> inline lsn_t log_t::write_buf() noexcept
1002
1021
buf + length, flush_buf);
1003
1022
... /* TODO: Update the LSN and adjust other code. */
1004
1023
#else
1005
- # ifdef HAVE_valgrind
1006
1024
MEM_MAKE_DEFINED (buf + length, (write_size_1 + 1 ) - length);
1025
+ buf[length]= 0 ; /* ensure that recovery catches EOF */
1026
+ #endif
1007
1027
if (UNIV_LIKELY_NULL (re_write_buf))
1028
+ {
1008
1029
MEM_MAKE_DEFINED (re_write_buf + length, (write_size_1 + 1 ) - length);
1009
- # endif
1010
- buf[length]= 0 ; /* allow recovery to catch EOF faster */
1011
- #endif
1030
+ re_write_buf[length]= 0 ;
1031
+ }
1012
1032
length= write_size_1 + 1 ;
1013
1033
}
1014
1034
else
@@ -1023,27 +1043,28 @@ template<bool release_latch> inline lsn_t log_t::write_buf() noexcept
1023
1043
(We want to avoid memset() while holding exclusive log_sys.latch)
1024
1044
This block will be overwritten later, once records beyond
1025
1045
the current LSN are generated. */
1026
- #ifdef HAVE_valgrind
1027
- MEM_MAKE_DEFINED (buf + length, (write_size_1 + 1 ) - new_buf_free);
1028
- if (UNIV_LIKELY_NULL (re_write_buf))
1029
- MEM_MAKE_DEFINED (re_write_buf + length, (write_size_1 + 1 ) -
1030
- new_buf_free);
1031
- #endif
1046
+ MEM_MAKE_DEFINED (buf + length, (write_size_1 + 1 ) - new_buf_free);
1032
1047
buf[length]= 0 ; /* allow recovery to catch EOF faster */
1033
1048
length&= ~write_size_1;
1034
1049
memcpy_aligned<16 >(flush_buf, buf + length, (new_buf_free + 15 ) & ~15 );
1035
1050
if (UNIV_LIKELY_NULL (re_write_buf))
1051
+ {
1052
+ MEM_MAKE_DEFINED (re_write_buf + length, (write_size_1 + 1 ) -
1053
+ new_buf_free);
1036
1054
memcpy_aligned<16 >(resize_flush_buf, re_write_buf + length,
1037
1055
(new_buf_free + 15 ) & ~15 );
1056
+ re_write_buf[length + new_buf_free]= 0 ;
1057
+ }
1038
1058
length+= write_size_1 + 1 ;
1039
1059
}
1040
1060
1041
1061
std::swap (buf, flush_buf);
1042
- std::swap (resize_buf, resize_flush_buf);
1062
+ if (UNIV_LIKELY_NULL (re_write_buf))
1063
+ std::swap (resize_buf, resize_flush_buf);
1043
1064
}
1044
1065
1045
1066
write_to_log++;
1046
- if (release_latch )
1067
+ if (resizing != RETAIN_LATCH )
1047
1068
latch.wr_unlock ();
1048
1069
1049
1070
DBUG_PRINT (" ib_log" , (" write " LSN_PF " to " LSN_PF " at " LSN_PF,
@@ -1103,7 +1124,7 @@ wait and check if an already running write is covering the request.
1103
1124
@param durable whether the write needs to be durable
1104
1125
@param callback log write completion callback */
1105
1126
void log_write_up_to (lsn_t lsn, bool durable,
1106
- const completion_callback *callback)
1127
+ const completion_callback *callback) noexcept
1107
1128
{
1108
1129
ut_ad (!srv_read_only_mode || log_sys.buf_free_ok ());
1109
1130
ut_ad (lsn != LSN_MAX);
@@ -1148,7 +1169,7 @@ void log_write_up_to(lsn_t lsn, bool durable,
1148
1169
group_commit_lock::ACQUIRED)
1149
1170
{
1150
1171
log_sys.latch .wr_lock (SRW_LOCK_CALL);
1151
- pending_write_lsn= write_lock.release (log_sys.write_buf < true > ());
1172
+ pending_write_lsn= write_lock.release (log_sys.writer ());
1152
1173
}
1153
1174
1154
1175
if (durable)
@@ -1165,6 +1186,23 @@ void log_write_up_to(lsn_t lsn, bool durable,
1165
1186
}
1166
1187
}
1167
1188
1189
+ static lsn_t log_writer () noexcept
1190
+ {
1191
+ return log_sys.write_buf <log_t ::NOT_RESIZING>();
1192
+ }
1193
+
1194
+ ATTRIBUTE_COLD static lsn_t log_writer_resizing () noexcept
1195
+ {
1196
+ return log_sys.write_buf <log_t ::RESIZING>();
1197
+ }
1198
+
1199
+ void log_t::writer_update () noexcept
1200
+ {
1201
+ ut_ad (latch_have_wr ());
1202
+ writer= resize_in_progress () ? log_writer_resizing : log_writer;
1203
+ mtr_t::finisher_update ();
1204
+ }
1205
+
1168
1206
/* * Write to the log file up to the last log entry.
1169
1207
@param durable whether to wait for a durable write to complete */
1170
1208
void log_buffer_flush_to_disk (bool durable)
@@ -1232,7 +1270,7 @@ ATTRIBUTE_COLD void log_write_and_flush()
1232
1270
else
1233
1271
#endif
1234
1272
{
1235
- const lsn_t lsn{log_sys.write_buf <false >()};
1273
+ const lsn_t lsn{log_sys.write_buf <log_t ::RETAIN_LATCH >()};
1236
1274
write_lock.release (lsn);
1237
1275
log_flush (lsn);
1238
1276
}
0 commit comments