Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
T
tarantool
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
core
tarantool
Commits
577ef3a7
Commit
577ef3a7
authored
12 years ago
by
Konstantin Osipov
Browse files
Options
Downloads
Patches
Plain Diff
Thread-based WAL writer: fix the bug with out of order confirm_lsn().
parent
eacb063c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
core/log_io.m
+59
-24
59 additions, 24 deletions
core/log_io.m
core/say.m
+1
-1
1 addition, 1 deletion
core/say.m
with
60 additions
and
25 deletions
core/log_io.m
+
59
−
24
View file @
577ef3a7
...
...
@@ -67,10 +67,11 @@ struct recovery_state *recovery_state;
struct
wal
_
writer
{
STAILQ
_
HEAD
(
wal
_
fifo
,
wal
_
write
_
request
)
input
;
STAILQ
_
HEAD
(
wal
_
fifo
,
wal
_
write
_
request
)
input
,
output
;
pthread
_
t
thread
;
pthread
_
mutex
_
t
mutex
;
pthread
_
cond
_
t
cond
;
ev
_
async
async
;
bool
is
_
shutdown
;
}
;
...
...
@@ -120,7 +121,7 @@ confirm_lsn(struct recovery_state *r, i64 lsn)
return
0
;
}
else
{
say
_
warn
(
"lsn double confirmed:%"
PRIi64
,
r
->
confirmed
_
lsn
)
;
say
_
warn
(
"lsn double confirmed:%"
PRIi64
,
lsn
)
;
}
return
-
1
;
...
...
@@ -1211,6 +1212,29 @@ wal_writer_init_once()
pthread_atfork(NULL, NULL, wal_writer_child);
}
static void
wal_writer_schedule(ev_watcher *watcher, int event __attribute__((unused)))
{
struct wal_writer *writer = watcher->data;
struct wal_fifo output;
tt_pthread_mutex_lock(&writer->mutex);
output = writer->output;
STAILQ_INIT(&writer->output);
tt_pthread_mutex_unlock(&writer->mutex);
/*
* Can't use STAILQ_FOREACH since fiber_call()
* destroys the list entry.
*/
struct wal_write_request *req = STAILQ_FIRST(&output);
while (req) {
struct fiber *f = req->fiber;
req = STAILQ_NEXT(req, wal_fifo_entry);
fiber_call(f);
}
}
static void
wal_writer_init(struct wal_writer *writer)
{
...
...
@@ -1238,6 +1262,10 @@ wal_writer_init(struct wal_writer *writer)
tt_pthread_condattr_destroy(&clock_monotonic);
STAILQ_INIT(&writer->input);
STAILQ_INIT(&writer->output);
ev_async_init(&writer->async, (void *) wal_writer_schedule);
writer->async.data = writer;
tt_pthread_once(&wal_writer_once, wal_writer_init_once);
}
...
...
@@ -1265,11 +1293,15 @@ wal_writer_start(struct recovery_state *state)
{
assert(state->writer == NULL);
assert(wal_writer.is_shutdown == false);
assert(STAILQ_EMPTY(&wal_writer.input));
assert(STAILQ_EMPTY(&wal_writer.output));
/* I. Initialize the state. */
wal_writer_init(&wal_writer);
state->writer = &wal_writer;
ev_async_start(&wal_writer.async);
/* II. Start the thread. */
if (pthread_create(&wal_writer.thread, NULL, wal_writer_thread,
...
...
@@ -1295,22 +1327,26 @@ wal_writer_stop(struct recovery_state *state)
tt_pthread_cond_signal(&writer->cond);
tt_pthread_mutex_unlock(&writer->mutex);
if (pthread_join(writer->thread, NULL) == 0) {
wal_writer_destroy(writer);
return 0;
}
say_syserror("WAL writer: thread join failed");
if (pthread_join(writer->thread, NULL) != 0)
goto error;
ev_async_stop(&writer->async);
wal_writer_destroy(writer);
return 0;
error:
/* We can't recover from this in any reasonable way. */
panic_syserror("WAL writer: thread join failed");
return -1;
}
struct wal_fifo
wal_writer_pop(struct wal_writer *writer, bool
wait
)
wal_writer_pop(struct wal_writer *writer, bool
input_was_empty
)
{
struct wal_fifo input;
do {
input = writer->input;
STAILQ_INIT(&writer->input);
if (STAILQ_EMPTY(&input) == false ||
wait
== false)
if (STAILQ_EMPTY(&input) == false ||
input_was_empty
== false)
break;
tt_pthread_cond_wait(&writer->cond, &writer->mutex);
} while (writer->is_shutdown == false);
...
...
@@ -1413,35 +1449,32 @@ wal_writer_thread(void *worker_args)
{
struct
recovery
_
state
*
r
=
worker
_
args
;
struct
wal
_
writer
*
writer
=
r
->
writer
;
struct wal_fifo output = STAILQ_HEAD_INITIALIZER(output)
;
bool
input
_
was
_
empty
=
true
;
struct
wal
_
write
_
request
*
req
;
tt
_
pthread
_
mutex
_
lock
(
&
writer
->
mutex
)
;
while
(
writer
->
is
_
shutdown
==
false
)
{
struct wal_fifo input =
wal_writer_pop(writer, STAILQ_EMPTY(&output));
struct
wal
_
fifo
input
=
wal
_
writer
_
pop
(
writer
,
input
_
was
_
empty
)
;
pthread
_
mutex
_
unlock
(
&
writer
->
mutex
)
;
/*
*
Check the old list of fibers to wakeup
*here*
* since we need
ed
a membar for
its
out_lsn's to
*
Wake
up
fibers
waiting
on
the
old
list
*
here
*
*
since
we
need
a
membar
for
request
out
_
lsn
'
s
to
*
sync
up
.
*/
STAILQ_FOREACH(req, &output, wal_fifo_entry) {
/*
* @todo:
* Even though wal_write() is not
* a cancellation point, check the fiber
* wasn't cancelled and recycled.
* */
fiber_wakeup(req->fiber);
}
if
(
input
_
was
_
empty
==
false
)
ev
_
async
_
send
(
&
writer
->
async
)
;
STAILQ
_
FOREACH
(
req
,
&
input
,
wal
_
fifo
_
entry
)
{
(
void
)
write
_
to
_
disk
(
r
,
req
)
;
}
output =
input;
input
_
was
_
empty
=
STAILQ
_
EMPTY
(
&
input
)
;
tt
_
pthread
_
mutex
_
lock
(
&
writer
->
mutex
)
;
STAILQ
_
CONCAT
(
&
writer
->
output
,
&
input
)
;
}
tt
_
pthread
_
mutex
_
unlock
(
&
writer
->
mutex
)
;
if
(
input
_
was
_
empty
==
false
)
ev
_
async
_
send
(
&
writer
->
async
)
;
write
_
to
_
disk
(
r
,
NULL
)
;
return
NULL
;
}
...
...
@@ -1478,6 +1511,8 @@ wal_write(struct recovery_state *r, u16 tag, u16 op, u64 cookie,
fiber
_
yield
()
;
assert
(
req
->
out
_
lsn
==
0
||
(
req
->
lsn
==
lsn
&&
req
->
out
_
lsn
==
lsn
))
;
return
req
->
out
_
lsn
==
0
?
-
1
:
0
;
}
...
...
This diff is collapsed.
Click to expand it.
core/say.m
+
1
−
1
View file @
577ef3a7
...
...
@@ -116,7 +116,7 @@ vsay(int level, const char *filename, int line, const char *error, const char *f
const
char
*
peer
_
name
=
fiber
_
peer
_
name
(
fiber
)
;
size
_
t
p
=
0
,
len
=
PIPE
_
BUF
;
const
char
*
f
;
static
char
buf
[
PIPE
_
BUF
]
;
static
__
thread
char
buf
[
PIPE
_
BUF
]
;
if
(
booting
)
{
fprintf
(
stderr
,
"%s: "
,
binary
_
filename
)
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment