Given an old-style binlog position with file name and file offset, find the corresponding gtid position. If the offset is not at an event boundary, give an error. Return NULL on ok, error message string on error. ToDo: Improve the performance of this by using binlog index files. */
| 1866 | ToDo: Improve the performance of this by using binlog index files. |
| 1867 | */ |
| 1868 | static const char * |
| 1869 | gtid_state_from_pos(const char *name, uint32 offset, |
| 1870 | slave_connection_state *gtid_state) |
| 1871 | { |
| 1872 | IO_CACHE cache; |
| 1873 | File file; |
| 1874 | const char *errormsg= NULL; |
| 1875 | bool found_gtid_list_event= false; |
| 1876 | bool found_format_description_event= false; |
| 1877 | bool valid_pos= false; |
| 1878 | enum_binlog_checksum_alg current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF; |
| 1879 | int err; |
| 1880 | String packet; |
| 1881 | Format_description_log_event *fdev= NULL; |
| 1882 | bool found_in_index; |
| 1883 | uint32 UNINIT_VAR(start_seek); |
| 1884 | bool seek_done= false; |
| 1885 | |
| 1886 | /* |
| 1887 | Try to lookup the position in the binlog gtid index. If found (as it will |
| 1888 | usually be unless the index is corrupted somehow), we can seek directly to |
| 1889 | a point at or just before the desired location, saving an expensive scan |
| 1890 | of the binlog file from the start. |
| 1891 | */ |
| 1892 | found_in_index= opt_binlog_gtid_index ? |
| 1893 | gtid_index_lookup_pos(name, offset, &start_seek, gtid_state) : |
| 1894 | false; |
| 1895 | if (found_in_index) |
| 1896 | found_gtid_list_event= true; |
| 1897 | else if (unlikely(gtid_state->load((const rpl_gtid *)NULL, 0))) |
| 1898 | { |
| 1899 | errormsg= "Internal error (out of memory?) initializing slave state " |
| 1900 | "while scanning binlog to find start position"; |
| 1901 | return errormsg; |
| 1902 | } |
| 1903 | |
| 1904 | if (unlikely((file= open_binlog(&cache, name, &errormsg)) == (File)-1)) |
| 1905 | return errormsg; |
| 1906 | |
| 1907 | if (!(fdev= new Format_description_log_event(4))) |
| 1908 | { |
| 1909 | errormsg= "Out of memory initializing format_description event " |
| 1910 | "while scanning binlog to find start position"; |
| 1911 | goto end; |
| 1912 | } |
| 1913 | |
| 1914 | /* |
| 1915 | First we need to find the initial GTID_LIST_EVENT. We need this even |
| 1916 | if the offset is at the very start of the binlog file. |
| 1917 | |
| 1918 | But if we do not find any GTID_LIST_EVENT, then this is an old binlog |
| 1919 | with no GTID information, so we return empty GTID state. |
| 1920 | */ |
| 1921 | for (;;) |
| 1922 | { |
| 1923 | Log_event_type typ; |
| 1924 | uint32 cur_pos; |
| 1925 |
no test coverage detected