Дневника на Георги Сотиров

Моят личен и професионален живот

2020-07-20

Излезе MySQL 8.0.21

В понеделник (13-и Юли) Оракъл пусна MySQL 8.0.21 сървър и свързани продукти, което е следващата версия по поддръжката от 8.0 сирите, която не съдържа много нови възможности за разработчици. Тези които забелязах са следните.

Нова JSON функция JSON_VALUE

Има нова, по стандарт SQL 2016 функция JSON_VALUE, която е същото като извикването на CAST(JSON_UNQUOTE( JSON_EXTRACT(json_doc, path) ) AS type). Тя прави кода по-кратък и ясен както и по-стандартен, но прекия ефект, е че опростява създаването на индекси по JSON полета премахвайки нуждата от създавани колони.

По-безопасна LOAD DATA LOCAL INFILE на клиенти

Проблема с тази команда беше, че сървъра може да поиска всеки файл (виж съображения за сигурност), затова сега има конфигурация load-data-local-dir, с която клиентите могат да определят какво е позволено. Надявам се, че поддръжка за командата вече ще бъде интегрирана в  Workbench, за да са по-бързи отдалечените зареждания на данни.

MySQL Shell

Вече има поддръжка за валидиране на JSON схема през X DevAPI с validation JSON обекта осигуряващо определена структура на документите създавани или обновявани в колекция. Вижте повече в статията JSON Schema Validation на X DevAPI Потребителско ръководство или в бележките към версията на Shell.

MySQL Workbench

Новата версия идва със синтактична поддръжка на различни езикови възможности на сървъри 8.0.19 и 8.0.20. Това оправя бъгове 98263 и 98266, които докладвах.

Разбира се има много нови възможности и подобрения, както и поправки на бъгове за които можете да прочетете в подробности в бележките към версията, а ако се интересувате само от основните неща тогава прегледайте статията в блога на MySQL сървър.

2020-05-23

Честит 25-ти Рожден Ден MySQL!

Днес, 23-ти Май 2020 г., MySQL навършва 25 години. За първи път се запознах с него по време на университетските ми години докато търсех безплатна и отворена релационна СУБД, за да уча и експериментирам с SQL. И го използвам от тогава. Така следвах развитието на "Най-популярната база данни с отворен код в света" през последните около 20 години от версии 3.2x насам. Годишнината е голяма. И така, какво означава MySQL за мен?
  • Първо и най-важно, MySQL е релационната (и не само) база от данни която избирам за личните ми и професионални проекти. За мен е лесно да измислям нови схеми на бази от данни в термините на MySQL и проектирам нови системи върху MySQL като система за бази от данни;
  • MySQL става все по-добър и по-добър с годините, което задържа интереса ми. Все още помня пристигането на:
    • 4.0 (със поддръжка на обединения, т.н.),
    • после 4.1 (подзаявки и подготвени изрази, т.н.),
    • после 5.0 (съхранени процедури, спусъци и изгледи, разпределени транзакции, т.н.),
    • после 5.1 (разделяне на таблица на дялове, XML и планировчик на събития, т.н),
    • после 5.5 (SIGNAL и RESIGNAL, PERFORMANCE_SCHEMA),
    • после 5.6 (пълнотекстово търсене за InnoDB, т.н.),
    • после 5.7 (JSON, именувани тригери, създавани колони, подсказки за оптимизатор, т.н.),
    • и по-скоро 8.0 (CTEs, прозоречни функции, подобрения по регулярни изрази, функция GROUPING, склад за документи, CHECK ограничения, LATERAL, функционални части на ключове и изрази по подразбиране и още много, много повече);
  • Изграждам MySQL сървър (и други продукти) за Slackware Linux от 2005 г., защото първоначално имах нужда от по-нови версии от предоставяните от официалното хранилище, а след това, защото Slackware превключи към MariaDB през 2013 г., но аз избрах да остана с MySQL. Това не значи, че не ползвам MariaDB въобще и в някои отношения вярвам, че е напред;
  • Докладвам бъгове на MySQL и свързани продукти, за да получа решение на проблемите (виж историята на някои от моите бъг доклади);
  • Пиша за MySQL през последните 2 години от излизането на MySQL 8.0, което ми помага да се запозная с новите възможности;
  • Също така представям MySQL от време на време, което ми помага да взаимодействам в обществото, да се уча и обменям идеи с по-опитните от мен;
  • Накрая, но определено не на последно място, има страхотно и много силно общество около MySQL, с което имах шанса да взаимодействам повече в последните 3 години. Това е което прави MySQL проекта силен толкова много години.
Казано просто MySQL е много повече от база данни за мен. MySQL беше с мен през значителна част от живота ми до сега и ме прави щастлив да виждам как базата продължава да се развива. Продължавам да смятам, че по-добрата поддръжка на SQL стандарта и новите възможности за разработчици трябваше да пристигнат по-рано, но по-добре късно отколкото никога. Също така разработката може да бъде по-отворена, но съм уверен, че бъдещето е отворено и светло.

За следващите 25 години и по-нататък! Честит рожден ден MySQL! Наздраве на всички, които използват и обичат MySQL!

    2020-05-03

    Излезе MySQL 8.0.20

    В Понеделник (27-ми Април) Oracle пусна MySQL 8.0.20 сървър и свързани продукти. Можете да проверите бележките към версията и официалната публикация. Фокусът на тази версия е компресия на транзакция в двоичен лог за спестяване на дисково пространство и мрежов трафик, така че няма много нови неща за разработчици. Все пак ето нещата, които забелязах в гореспоменатите ресурси.
    • Нови подсказки на оптимизатора на ниво индекс за съществуващи индекс подсказки (обърнете внимание на разликата!), които включват следните:
      • GROUP_INDEX/NO_GROUP_INDEX като равнозначещи на FORCE INDEX FOR GROUP BY/IGNORE INDEX FOR GROUP BY индекс подсказки;
      • INDEX/NO_INDEX като равнозначещи на FORCE INDEX/IGNORE INDEX индекс подсказки;
      • JOIN_INDEX/NO_JOIN_INDEX като равнозначещи на FORCE INDEX FOR JOIN/IGNORE INDEX FOR JOIN индекс подсказки;
      • ORDER_INDEX/NO_ORDER_INDEX като равнозначещи на FORCE INDEX FOR ORDER BY/IGNORE INDEX FOR ORDER BY индекс подсказки;
    • Оптимизацията хеш съединение вече поддържа също външно, анти и полу типове съединения, която значи, че за да работи хеш съединението вече не е нужно да има поне едно условие за равенство.
    • Има няколко подобрения по EXPLAIN израза:
      • с FORMAT=TREE включва нова inversion информация за прозоречни функции. За съжаление не намерих повече информация за това;
      • с FORMAT=TREE предоставя повече информация за оценени прозоречни функции съвпадаща с тази за обикновени съвкупности. Вече ще виждате редове "Window aggregate with buffering";
      • за ANALYZE вече има възможността за спиране на изпълнението с KILL QUERY или CTRL+C клавишна комбинация на команден ред;
      • ANALYZE вече трябва да поддържа FORMAT параметър с единствено възможна стойност TREE както е отразено в бележките към версията и наръчника, но за мен това предизвиква грешка.

        mysql> EXPLAIN ANALYZE FORMAT=TREE SELECT 1+1;
        ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FORMAT=TREE SELECT 1+1' at line 1


        Както и да е, надявам се това е първата стъпка в изпълнението на поддръжка за тази команда в Workbench в бъдеще (виж бъг 97282).
    Има няколко оттегляния, които включват:
    Няма промени в MySQL 8.0.20 Workbench, но все пак има нова версия и бележки към нея.

    В очакване на следващата версия можете да обновите кода си, за да избегнете изненади от премахнати преди това оттеглени функционалности.

    2020-02-29

    Миграциите към Git и GitHub продължават

    Миналата година започнах миграция от CVS към Git и GitHub (виж Първи миграции от CVS към Git), което е нещо което исках да започна още през 2018-та (виж Миграция към Git и GitHub), а планирах дори от по-отдавна. Е, оказа се трудна задача, защото все още мигрирам, тъй като много от CVS хранилищата ми изискваха поправки, така че историята да може да бъде правилно прехвърлена в Git. По време на миграциите бях изненадан колко небрежен съм бил към кода си, защото открих непродадени промени от преди чак 10 години, повредени файлове с ревизии и различни несъответствия в историята. След като мигрирах някои проекти веднага започнах да работя по обновявания и поправки, така че вече продължавам работата си в Git. Също така пуснах непрекъсната интеграция за някои проекти използвайки Travis CI и GitHub Actions.

    В момента мигрирам Slackware скриптовете си за изграждане на пакети, които са колекция от над 300 шел скрипта и свързаните с тях файлове организирани като отделни хранилища в отделни директории, но под един корен. В CVS това беше напълно в реда на нещата, но не произвежда добра история в Git, защото етикетите за версии или клонове (напр. FFmpeg-3_4_7 или MySQL-5_5) са специфични само за определен скрипт и използвани само от файловете в съответната му директория. Затова реших да ги мигрирам отделно и да ги обединя в друго хранилище с под модули. Има доста проблеми и с тази миграция.

    Това са някои от проблемите:
    • етикети или клонове с подобни имена (напр. TEST-123 и TEST_123). Тези са лесни за оправяне - просто трия грешния етикет/клон;
    • неправилно поставени етикети или клонове. Тъй като в CVS поставях етикети и започвах клонове както е нужно някои етикети и клонове бяха поставени на различни файлове в различно време, което в Git историята се отразява като подавания със съобщение "This commit was manufactured by cvs2git to create tag 'TEST-123'" или "This commit was manufactured by cvs2git to create branch 'TEST-123'" с файлове които са добавени, премахнати или променени, за да се нагласи историята за съответния етикет или клон. Оправям такива проблеми с пренареждане на проблемните подавания, което е лесно само със смяна на датата във файла с ревизии в хранилището, но отнема време да се прегледа и разбере причината;
    • неизползвани файлове, които не са изтрити в историята. Това също предизвиква подавания със съобщения като споменатите в предишната точка. Тези проблеми оправям с изтриване на неизползваните файлове с минала дата, така че те да не се взимат в предвид от следващи подавания;
    • файлове принадлежащи на клон, но подадени в ствола вместо това. Подобно на предходното. В някои случаи, има файлове, които трябва да съществуват само по някакъв клон (напр. като кръпки за поправка на проблеми с конкретна версия на софтуера), но са били подадени в ствола. Тъй като в CVS няма голяма разлика между етикети и клонове е било достатъчно да има етикет на промените, за да се изваждат правилно. Премествам такива от ствола в клон, което означава изтриване на ревизиите от ствола и преместването им върху клона;
    • правописни грешки. Тъй като най-вече подавах към CVS от команден ред и не използвах проверка на правописа имам много съобщения към подавания с правописни грешки, които дразнят очите ми. Поправям ги след първоначална миграция към Git, за да мога да проверя всички съобщения наведнъж.
    Два инструмента се оказа от голяма помощ след миграция - licensee и github-linguist. Използвам първия, за да проверя дали лиценза се открива правилно. Имах някои проблеми (виж бъгове 361 и 392) с някои от проектите ми, затова сега проверявам преди да бутна към GitHub. Втория е полезен за фина настройка на откриването на езиците (напр. искам да виждам просто SQL, а не PLSQL, PLpgSQL, SQLPL или TSQL, които лингвист би открил, въпреки че всичките ми публикувани SQL изходни кодове са за MySQL. И за мен SQL е код, не данни).

    Както и да е публикувам това, за да отбележа, че миграциите ми към Git продължават. Постигнах голям напредък миналата година мигрирайки 28 хранилища. А тази година досега мигрирах още 114. Така надявам се до края на годината ще бъда свободен от ползване на CVS (или поне само по изключение). Първоначално планувах да мигрирам всичко, но вече смятам да пропусна някои проекти и примери с по-ниска стойност, които ако е нужно, мога да мигрирам по-късно.

    2020-01-17

    Излезе MySQL 8.0.19 набор от продукти

    MySQL 8.0.19 набора от продукти включващ Community Server, Router и Shell, беше пуснат в Понедленик (13.01). Фокуса на тези версии е новата InnoDB ReplicaSet функционалност, която улеснява управлението на класическа MySQL репликация с един първичен и множество вторични по същия начин както пускането на Групова репликация с InnoDB Cluster. Можете да прочетете повече за нея в статията The all new MySQL InnoDB ReplicaSet. Освен това има някои подобрения за които можете да прочетете отдолу.

    SQL синтаксис

    Сървъра вече разбира по-общия и стандартен ALTER TABLE … DROP/ALTER CONSTRAINT синтаксис за което чуруликнах по-рано. Това е искане за функционалност към MySQL 4.1 от преди повече от 15 години. Можете да откриете повече в Foreign Keys and Other Constraints секцията на ALTER TABLE статията в документацията.

    Конструктори на стойности са друго подобрение към стандарта позволяващо създаването на редове в VALUES израза (да не се бърка с ключовата дума VALUES за INSERT изрза). Поради конфликт с името на VALUES функцията е необходимо да се ползва разширената форма с  ROW конструктор. Основно това означава, че самостоятелния израз VALUES ROW(1), ROW(2), ROW(3) сега се разбира правилно от сървъра. VALUES израза може да се използва също в обединения, съединения, като производна таблица и в други случаи където можете да ползвате SELECT. Виж статията VALUES израз в документацията за повече подробности.

    Новия TABLE израз реализира друга възможност от стандарта - явни клаузи за таблица. Той също може да се ползва като SELECT, защото TABLE t е също като SELECT * FROM t, така че може да се ползва в обединения, с INTO, в IN подзаявка и всякъде другаде където SELECT може да се ползва.

    Интересно ново допълнение е LIMIT клаузата за рекурсивни CTEs, която позволява дебъгването на изрази генериращи твърде много резултати. Идеята е просто да се ограничи резултата от рекурсивния CTE до някакъв разумен брой редове (напр. 10, 100, и т.н.), за да можете да видите създадения изход и да можете да разберете как и защо се създава така. Тази нова възможност се покрива от статията A new, simple way to figure out why your recursive CTE is running away и в Limiting Common Table Expression Recursion секцията на WITH (Common Table Expressions) в документацията.

    Вече е възможно да се ползва псевдоним за новия ред и допълнително колони с INSERT ... ON DUPLICATE KEY UPDATE израз след VALUES или SET клаузи с изпулването на AS ключова дума. Предполагам това е първата стъпка към премахването на VALUES функцията (виж отгоре) за по-добра поддръжка на стандарта. Можете да намерите повече в статията ON DUPLICATE KEY UPDATE Statement.

    Промени по типове данни

    Типовете TIMESTAMP и DATETIME вече могат да включват информация за времева зона като корекция (напр. +02:00 или -08:00) добавена към стойността. Подробностите са в статията The DATE, DATETIME, and TIMESTAMP Types в документацията.

    Типа YEAR(4) (т.е. с явна дължина на показване) и (недокументираният) UNSIGNED атрибут за YEAR са вече остарели и ще бъдат премахнати в бъдеще. Това следва други премахвания на дължини на показване и други атрибути с 8.0.17 за които писах преди, така че разработчиците трябва да проверят и поправят всеки SQL скрипт използващ остарели типове данни и атрибути. С тази версия изрази, които печатат определения на типове данни (напр. SHOW CREATE TABLE) вече не показват дължина на показване за целочислени типове с изключение на TINYINT(1)  и ZEROFILL  атрибута.

    Други промени в сървър

    Потребителски определени функции (UDFs) вече могат да определят кодировката и подреждането на низови аргументи както забелязах по-рано. Можете да прочетете повече за това в статията A Tale of UDFs with Character Sets.

    Вече има стандартни INFORMATION_SCHEMA изгледи свързани с роли като ADMINISTRABLE_ROLE_AUTHORIZATION, APPLICABLE_ROLES, ENABLED_ROLES, ROLE_COLUMN_GRANTS, ROLE_ROUTINE_GRANTS и ROLE_TABLE_GRANTS.

    InnoDB машината вече поддържа ефективно взимане на проби от данни за хистограми. Взимането на проби вече не изисква пълно сканиране на таблица, което може да е скъпо за големи таблици, а взима проби от страниците с данни на клъстерирания индекс вместо това. Трябва да пробвам при първа възможност.

    Функцията JSON_SCHEMA_VALID вече връща подробна информация за причините за пропаднала валидация с използването на SHOW WARNINGS.

    Други забележителни промени са възможността за заключване на потребителски сметки след FAILED_LOGIN_ATTEMPTS опита за вход за PASSWORD_LOCK_TIME дни (виж Failed-Login Tracking and Temporary Account Locking), компресия в X протокол (виж Connection Compression with X Plugin) и много други както можете да откриете в бележките към версията.

    Бъгове оправени в сървър

    Докладвания преди проблем с EXPLAIN ANALYZE неизпълняващ и докладващ заявки в SELECT списъка беше оправен (виж бъг 97296).

    Workbench

    Четейки в бележките към новата версия, че "The following MySQL server language features are now supported: value references in INSERT statements, new options (TLS version, cipher suite, compression, and privilege check) in CHANGE MASTER TO replication statements, random passwords in CREATE USER and ALTER USER statements, EXPLAIN ANALYZE, and binary collation names." бях обнадежден, че приложението най-накрая наваксва със сървъра, но това беше докато на прегледах новия SQL синтаксис (виж отгоре).

    Два от бъговете, които докладвах преди бяха оправени - 97416 (за EXPLAIN ANALYZE) и 97281 (за ANALYZE TABLE ... UPDATE HISTOGRAM), но отворих два нови за TABLE (виж бъг 98263) и VALUES (виж бъг 98266) изразите. Тези проблеми са очевидни, но все още ми е странно как продължават да се появяват.
    Има нов елемент "Copy Row (with names, tab separated)" в контекстното меню за копиране на заглавия и редове от получените данни с табулация като разделител, което прави лесно преместването на данни към Excel или LibreOffice Calc.

    Щастливо ползване и експериментиране с новите MySQL версии!

    2020-01-09

    Използване на xrdp с различни Линукси и проблем на Fedora

    Използвам различни Линукси във виртуални машини от повече от 15 години, за да поддържам уменията си актуални. Просто не е достатъчно да познаваш една Линукс дистрибуция, а трябва да познаваш поне основните такива (напр. Debian, RPM или основани на друг пакетен мениджър такива). Затова отделно от Slackware, редовно ползвам Debian, Ubuntu, Fedora, OpenSuSE, CentOS и от скоро Oracle Linux (заради Oracle XE). През годините, експериментирах също с Gentoo, FreeBSD, OpenBSD, NetBSD и други.
    Това от което веднага имам нужда във всяка от тези е сигурна обвивка (SSH) разбира се, за да мога да пиша команди отдалечено. Обаче, също искам да работя и си играя с GUI програми, так че имам нужда от отдалечен графичен достъп. През годините ползвах VNC и NoMachine, но никога не съм ги харесвал по различни парични. Това което винаги ми е липсвало в Linux беше лесен достъп като RDP с действително управление на сесии и всички други благини което е леко и здраво (напр. NoMachine също управлява сесии, но кодира видео на десктопа, което прави картината замъглена и често не работи на Линукс виртуалните ми машини след надграждания).
    Така открих xrdp, което е "RDP сървър с отворен код". Лесен за инсталиране, настройка и пускане на Debian, Ubuntu и OpenSuSE и просто работи. Инсталацията за Fedora изисква някои допълнителни стъпки, които са описани в README.Fedora от отговорника за xrdp пакета Божан Сможвер. По подразбиране xrdp на Fedora работи само с VNC сесии, но вече казах, че не го харесвам, така че предпочитам да ползвам Xorg както с другите ми Линукси. Ще резюмирам стъпките тук:
    1. Инсталация на нужните пакети: dnf install xrdp xorgrdp
    2. Промяна на /etc/xrdp/xrdp.ini и разрешаване на Xorg сесии;
    3. Разрешаване на достъп за всички или определени потребители, напр. echo "allowed_users = anybody" >> /etc/X11/Xwrapper.config (виж оше бъг 1450720);
    4. Разрешаване на порт 3389 на защитната стена, напр. firewall-cmd --zone=dmz --add-port=3389/tcp
    5. Насочване на RDP клиента към Линукс машината и забава.
    Е, поне до вчера. След надграждане на Fedora виртуалната ми машина до Fedora 31 RDP връзката спря да работи с Xorg сесии, въпреки че VNC сесиите си работеха. Журнала на xrdp в /var/log/xrdp-session.log предполагаше, че Xorg сесията се чупи точно след като се пусне, така че получавах празен екран.

    [20200109-10:12:53] [INFO ] setpriv --no-new-privs Xorg :10 -auth .Xauthority -config xrdp/xorg.conf -noreset -nolisten tcp -logfile .xorgxrdp.%s.log
    [20200109-10:12:53] [CORE ] waiting for window manager (pid 4902) to exit
    [20200109-10:12:57] [CORE ] window manager (pid 4902) did exit, cleaning up session
    [20200109-10:12:57] [INFO ] calling auth_stop_session and auth_end from pid 4877

    Разследвайки причината, забелязах следното в журнала (напр. с journalctl -r):

    Jan 09 10:12:55 fedora systemd[4881]: Failed to start GNOME Shell on X11.
    Jan 09 10:12:55 fedora systemd[4881]: gnome-shell-x11.service: Failed with result 'protocol'.
    Jan 09 10:12:55 fedora gnome-shell[5157]:   Current serial number in output stream:  359
    Jan 09 10:12:55 fedora gnome-shell[5157]:   Serial number of failed request:  358
    Jan 09 10:12:55 fedora gnome-shell[5157]:   Minor opcode of failed request:  7 (RRSetScreenSize)
    Jan 09 10:12:55 fedora gnome-shell[5157]:   Major opcode of failed request:  139 (RANDR)
    Jan 09 10:12:55 fedora gnome-shell[5157]: X Error of failed request:  BadMatch (invalid parameter attributes)
    Jan 09 10:12:55 fedora xrdp-sesman[4870]: rdpRRScreenSetSize: not allowing resize
    Jan 09 10:12:55 fedora xrdp-sesman[4870]: rdpRRScreenSetSize: width 1688 height 932 mmWidth 447 mmHeight 247
    Jan 09 10:12:55 fedora gnome-shell[5157]: Xlib:  extension "DPMS" missing on display ":10.0".
    Jan 09 10:12:55 fedora xrdp-sesman[4870]: rdpRRGetInfo:

    Значи gnome-shell всъщност пропадаше. Първоначално, намерих бъг 1575792, който изглежда сходен, но не е бил решен. В крайна сметка, проблема се оказа в последната версия на xorgxrdp 0.2.12 (виж проблема #156). Трябваше просто да върна версията на xorgxrdp до 0.2.11, с насилствено инсталиране на xorgxrdp пакета от RHEL 8 ето така:

    rpm --nodeps -i xorgxrdp-0.2.11-1.el8.x86_64.rpm

    И нещата се върнаха към нормалното.

    Обновяване 2020-01-14: Разбира се добре е да изключите пакета xorgxrdp от обновявания (виж Excluding Packages From Transactions) или просто echo "excludepkgs=xorgxrdp" >> /etc/dnf/dnf.conf като едноредова команда.

    Щастливо ползване на любимата ви Линукс дистрибуция!

    2019-12-25

    Bugzilla на Български в GitHub

    Преди точно 14 години на този ден качих локализацията на Bugzilla 2.18.1 в хранилището на проекта Mozilla-BG в OpenFMI. Обмислях използването на Bugzilla като система за следене на бъгове за домашния ми сървър от лятото на 2005 и когато разглеждах проекта забелязах, че няма локализация на български, така че реших да съдействам. Превода беше направен през лятото на 2005 и през есента започнах да търся начин да го публикувам. Първоначално си мислех за SourceForge, но в крайна сметка реших да стана част от проекта Mozilla-BG след като бях поканен от Огнян Кулев.
    Локализацията беше преместена в BitBucket през 2012 след като OpenFMI беше изведен от експлоатация, така че хранилището беше преобразувано от Subversion (SVN) към Mercurial (Hg). Тогава някои проблеми с SVN хранилището станаха очевидни, но не намерих време да ги оправя до сега. Е, беше време да мигрирам проекта към Git и да го публикувам в GitHub, което постигнах миналата седмица. Проекта Bugzilla-BG е вече на GitHub с цялата си история от Декември 2005. И от тогава можехте да пробвате локализацията на Sotirov-BG.Net Bugzilla.
    Локализацията измина дълъг път от CVS на домашния ми сървър първоначално към SVN, после Hg и най-накрая в Git. Единствения ми проект минал по този път :-)

    Забавлявайте се!
    Весела Коледа!

    2019-12-05

    Режим картина-в-картината в Firefox 71

    Firefox 71 излезе преди два дни (виж бележки към версията) и аз вече абсолютно харесвам новия режим на картина-в-картината за просвирване на видеоклипове докато сърфирате. Наистина е важно за мен, защото това е обичайния начин по който сърфирам в днешно време - да имам видео изпълняващо се на заден план и слушайки го докато сърфирам уебсайтове. Единствения недостатък беше, че трябваше да превключвам към раздела с видеото от време на време, когато исках наистина да видя какво върви. Това понякога изискваше търсенето на раздела, защото обичайно имам много раздели отворени в различни групи (организирани с  Panorama View разширението).
    Сега моето онлайн изживяване е доста по-приятно, защото мога просто да пусна видео, да го извадя в отделен малък прозорец където ми харесва на екрана и да продължа със сърфирането или правенето на нещо друго. Така мога да продължа да държа под око видеото дори когато се прехвърля извън Firefox. Супер полезно е дори когато работя върху нещо, защото нормално използвам много онлайн ресурси. Новата възможност е достъпна само под Windows за сега, но  Mozilla обещава да бъде достъпна за MacOS и Linux със следващата версия очаквана след около месец.
    Благодаря Mozilla, за това че постоянно подобряваш онлайн изживяването ми!

    2019-10-18

    Нови възможности в MySQL 8.0.18

    В понеделник, Oracle пусна MySQL 8.0.18 (виж още бележките към версията) и за разлика предходните версии имаше доста информация за това какво ще бъде включено в тази. лично присъствах на няколко представяния и четох някои публикации в социалните мрежи. Както вече писах основните нови възможности в тази версия са хеш съединения и EXPLAIN ANALYZE, които целят съответно да подобрят производителността на някои заявки и дадат по-добра представа за това как плана на оптимизатора се сравнява с действителното изпълнение.

    Оптимизация с хеш съединение

    Преди 8.0.18 единствения тип съединение извършван от MySQL беше вложения цикъл (цикъл в цикъл, вътрешен цикъл във външен цикъл). И имаше два алгоритъма изпълняващи го:
    • Nested-Loop Join - най-простия където всеки ред от външния цикъл се подава към вътрешния цикъл за обработка. Очевидния недостатък на този е, че вътрешната таблица трябва да бъде четена много пъти.
    • Block Nested Loop (BNL) - използва буфериране на редове от външната таблица, за да намали броя на пъти в които вътрешната таблица се чете. В този случай, вместо да се подава само един ред към вътрешния цикъл множество редове от буфера могат да бъдат подадени наведнъж. Това значително намалява броя пъти в които вътрешната таблица трябва да бъде четена. Разбира се това изисква повече памет (виж join_buffer_size). Този алгоритъм се използва за range, index или ALL типове съединения.
    Има също и Batched Key Access (BKA) алгоритъм, който използва буфериране както BNL, но поставя ключовете на редовете в буфера и ги подава наведнъж към машината на базата данни за намиране в индекса. Ключовете след това се ползват за извличане на редове от вътрешната таблица. Този алгоритъм може да се ползва когато има достъп чрез индекс към вътрешната таблица.

    Тук идват хеш съединенията. Идеята е да се построи хеш таблица на стойностите от външната таблица, която нормално е най-малката. След това се чете вътрешната таблица и се търсят съвпадения в хеш таблицата. Така и двете таблици в най-добрия случай могат да бъдат прочетени само по веднъж. Хеш съединенията са най-подходящи за големи резултати където не могат да се ползват индекси. Поради тяхната природа те са полезни само за съединения с равенство. От 8.0.18 MySQL ще избере хеш съединение пред BNL за всяка заявка, която използва условие с равенство за съединение (напр. ref или eq_ref типове съединения) и не ползва индекси. Да пробваме.

    За примера, добих нова таблица с име job_sal с диапазон на заплати според позиция към схемата dept_emp и също създадох 1 милион повече служители. Сега да кажем, че искате да намерите всички служители с заплата извън диапазона. Аз бих написал заявка като тази:

    SELECT E.ename, E.sal, JS.sal_min, JS.sal_max
      FROM emp     E,

           job_sal JS
     WHERE E.job = JS.job

       AND E.sal NOT BETWEEN JS.sal_min AND JS.sal_max;


    Която като се има в предвид липсата на индекси ще бъде изпълнена с BNL алгоритъм в MySQL преди 8.0.18, но в новата версия същата заявка ще се възползва от оптимизацията с хеш съединение както е показано в следващия план за изпълнение в дървовиден формат:

    +----------------------------------------------------------------------------------------+
    | EXPLAIN                                                                                |
    +----------------------------------------------------------------------------------------+
    | -> Filter: (E.sal not between JS.sal_min and JS.sal_max)  (cost=499211.71 rows=442901)
        -> Inner hash join (E.job = JS.job)  (cost=499211.71 rows=442901)
            -> Table scan on E  (cost=1962.39 rows=996514)
            -> Hash
                -> Table scan on JS  (cost=0.75 rows=5)
     |
    +----------------------------------------------------------------------------------------+
    1 row in set (0.0023 sec)


    Visual Explain Plan
    Плана разкрива, че за по-малката таблица JS ще бъде хеширана и съединението ще бъде изпълнено с използването на хеш таблица. За съжаление, оптимизацията с хеш съединение не е видима в традиционния план за изпълнение, JSON и така в MySQL Workbench. Визуалния план за изпълнение (виж вдясно) така ще бъде подвеждащ показвайки BNL алгоритъм за съединението. Това е разбираемо, защото оптимизацията с хеш съединение е възможна само с новия изпълнител на итеративни алгоритми, който всъщност създава плана за изпълнение в дървовиден (TREE) формат. Този изпълнител не може да обясни някои заявки, така че можете да видите само съобщението "not executable by iterator executor". Обаче, наистина се надявам това да бъде подобрено в следващи версии, защото плана за изпълнение трябва да бъде последователна между форматите. Докладвах заявка за функционалност като бъг 97280.

    Пробвах производителността на заявката за 1 милион служители и времето за изпълнение беше 0.89 сек. Забраняването на оптимизацията с хеш съединение с NO_HASH_JOIN подсказката увеличи времето за изпълнение до 1.26 сек. Хеш съединението със сигурност ще бъде много по-благотворно когато външната таблица има повече редове.

    EXPLAIN ANALYZE

    Тази нова възможност също идва върху дървовидния (TREE) план за изпълнение и и представлява нещо като инструмент за профилиране, защото освен информация за това как оптимизатора планира да изпълни заявката (виж отгоре) има също така информация от действителното ѝ изпълнение. Тази информация включва:
    • времето за връщане на първия ред (в мс);
    • времето за връщане на всички редове (в мс);
    • броя на прочетените редове;
    • броя цикли.
    Тя прави възможно сравнението на оценките на оптимизатора към действителното изпълнение на заявката. Да пробваме с предишната заявка. Нарочно съм скъсил изхода.

    +-------------------------------------------------------------------------------------------------------+
    | EXPLAIN                                                                                               |
    +-------------------------------------------------------------------------------------------------------+
    | -> Filter: (E.sal not between JS.sal_min and JS.sal_max)
           (cost=502072.82 rows=442901) (actual time=0.372..747.742 rows=915768 loops=1)
        -> Inner hash join (E.job = JS.job)
             (cost=502072.82 rows=442901) (actual time=0.355..575.011 rows=1000014 loops=1)
            -> Table scan on E  (cost=2534.62 rows=996514) (actual time=0.185..353.877 rows=1000014 loops=1)
            -> Hash
                -> Table scan on JS  (cost=0.75 rows=5) (actual time=0.133..0.144 rows=5 loops=1)
     |
    +-------------------------------------------------------------------------------------------------------+
    1 row in set (0.7754 sec)


    Ако ви изглежда познато проверете EXPLAIN ANALYZE на PostgreSQL. Моля, забележете, че времената са в милисекунди, не секунди! Мисля, че е лесно да се забележи, че броя редове оценени от оптимизатора за четенето на таблица E се различава, защото статистиките за телицата не са точни. Добавих 1 милион редове към таблица emp, така че трябва да увелича броя на пробните страници (виж innodb_stats_persistent_sample_pages) и пусна ANALYZE TABLE отново. След като го напраих оценката на оптимизатора и действителния брой редове съвпадат. Обаче, оптимизатора е също така в грешка за редовете за операциите от по-горно ниво - хеш съединението и филтъра, но това не може да се оправи със статистики за индекси. Според Norvald H. Ryeng (виж неговата статия MySQL EXPLAIN ANALYZE) както "оценения, така и действителния брой" редове "са осреднени върху всички цикли", но аз имам само един цикъл за всички операции в плана.

    Във всеки случай EXPLAIN ANALYZE е чудесно допълнение към инструментариума на оптимизатора. За съжаление, нито TREE формат нито EXPLAIN ANALYZE са достъпни дори в последния MySQL Workbench, така че още една заявка за функционалност от мен като бъг 97282.

    MySQL е само OpenSSL

    С тази версия поддръжката на yaSSL и WolfSSL библиотеките са премахва, така че MySQL може да се компилира само с OpenSSL. Аз лично винаги съм изграждал MySQL с OpenSSL (т.е. използвайки ключа -DWITH_SSL=system), защото това е което идва с Slackware, но разбира се по-важното е, че "комбинацията MySQL/OpenSSL е много добре изпробвана и доказана в продукция" както Georgi Kodinov обяснява в публикацията си MySQL is OpenSSL-only now !.

    Пространствен

    Функцията ST_Distance вече приема SRS аргуменити от всички геометрични типове, а не само аргументи от типове Point и Point, или Point и MultiPoint както преди.
    Щастливо ползване на MySQL!

    Обновена 2019-11-09: Това, че времената са в милисекунди не беше указано в наръчника, така че въведох бъг 97492, защото мисля също, че ще бъде добре единицата да се печата до времената.

    2019-09-29

    Нови използвания на TREE план за изпълнение в MySQL 8.0.18

    Както писах през Юни (виж Формат на план за изпълнение TREE в MySQL 8.0.16) нов формат на план за изпълнение беше въведен - TREE. Това беше представяне на операциите предприети от оптимизатора за задоволяването на заявка в форма с отстъпи като дърво. Новия формат беше определен като експериментален, затова чаках да видя как ще се развие в следващите версии. Е, миналия Петък докато разглеждах наръчника забелязах, че е обновен за две нови възможности идващи в MySQL 8.0.18:
    • HASH съединения ще бъдат видими само в TREE формат. Намирам това за странно, защото бихте очаквали да видите тази операция без значение от формата на плана, така че се надявам да бъде разширено в бъдеще.
    • EXPLAIN ANALYZE всъщност ще изпълнява заявката и ще дава информация за времето на изпълнение. Ще включва също и допълнителна информация на база итератор относно това как оценката на оптимизатора се сравнява с действителното изпълнение.
    Вече съм нетърпелив да пробвам новата версия, която предполагам ще бъде пусната някъде към средата на Октомври. Останете на линия, тъй като ще пиша за тези нови възможности когато пристигнат и имам възможност да си поиграя с тях.