Commit 23504368 authored by Marc Alff's avatar Marc Alff

Bug#51447 performance schema evil twin files

Before this fix, the performance schema file instrumentation would treat:
- a relative path to a file
- an absolute path to the same file
as two different files.

This would lead to:
- separate aggregation counters
- file leaks when a file is removed.

With this fix, a relative and absolute path are resolved to the same file instrument.
parent 2e9d7d78
......@@ -11,3 +11,17 @@ create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT;
ERROR HY000: Invalid performance_schema usage.
create table performance_schema.t1(a int);
ERROR 42000: CREATE command denied to user 'root'@'localhost' for table 't1'
drop table if exists test.ghost;
create table test.ghost (a int, b int);
alter table test.ghost add index index_a(a);
alter table test.ghost add index index_b(b);
insert into test.ghost values (1, 3);
insert into test.ghost values (2, 4);
select * from test.ghost;
a b
1 3
2 4
drop table test.ghost;
select * from performance_schema.FILE_INSTANCES
where file_name like "%ghost%";
FILE_NAME EVENT_NAME OPEN_COUNT
......@@ -55,3 +55,24 @@ create table test.t1 like performance_schema.EVENTS_WAITS_CURRENT;
--error ER_TABLEACCESS_DENIED_ERROR
create table performance_schema.t1(a int);
#
# Bug#51447 performance schema evil twin files
#
--disable_warnings
drop table if exists test.ghost;
--enable_warnings
create table test.ghost (a int, b int);
alter table test.ghost add index index_a(a);
alter table test.ghost add index index_b(b);
insert into test.ghost values (1, 3);
insert into test.ghost values (2, 4);
select * from test.ghost;
drop table test.ghost;
# Shoud return nothing
select * from performance_schema.FILE_INSTANCES
where file_name like "%ghost%";
......@@ -746,8 +746,23 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
}
}
if (len >= sizeof(pfs->m_filename))
len= sizeof(pfs->m_filename) - 1;
/*
Normalize the file name to avoid duplicates when using aliases:
- absolute or relative paths
- symbolic links
*/
char buffer[FN_REFLEN];
const char *normalized_filename;
int normalized_length;
/*
Ignore errors, the file may not exist.
my_realpath always provide a best effort result in buffer.
*/
(void) my_realpath(buffer, filename, MYF(0));
normalized_filename= buffer;
normalized_length= strlen(normalized_filename);
PFS_file **entry;
uint retry_count= 0;
......@@ -755,7 +770,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
search:
entry= reinterpret_cast<PFS_file**>
(lf_hash_search(&filename_hash, thread->m_filename_hash_pins,
filename, len));
normalized_filename, normalized_length));
if (entry && (entry != MY_ERRPTR))
{
pfs= *entry;
......@@ -783,9 +798,9 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
if (pfs->m_lock.free_to_dirty())
{
pfs->m_class= klass;
strncpy(pfs->m_filename, filename, len);
pfs->m_filename[len]= '\0';
pfs->m_filename_length= len;
strncpy(pfs->m_filename, normalized_filename, normalized_length);
pfs->m_filename[normalized_length]= '\0';
pfs->m_filename_length= normalized_length;
pfs->m_file_stat.m_open_count= 1;
pfs->m_wait_stat.m_control_flag=
&flag_events_waits_summary_by_instance;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment