Pull to refresh
129
Alexey Kopytov@kaamos

User

26
Subscribers
Send message
Я думаю, бытовые CMS вполне попадают в категорию «legacy», про который я и написал.
Здесь тяжело давать конкретные рекомендации, ничего не зная о нагрузке и не видя метрик. В следующем посте я собирался предложить варианты и объяснить плюсы/минусы/подводные камни. В каких-то случаях DRBD вполне себе реализует физическую репликацию. В каких-то можно посмотреть на read-free репликацию в TokuDB. А в каких-то просто сервер не настроен грамотно.
Да. Только это всё не о том, и никак не отвечает на заданные мною вопросы.
Вы лучше попробуйте ответить на вопросы зачем вообще нужен extra_float_digits и почему extra_float_digits=3 не включен по умолчанию, если это единственный режим, в котором PostgreSQL печатает корректные значения. Для себя ответить, не для меня. Я ответ знаю.
Света, объясни мне, пожалуйста, как всё вышеперечисленное может повлиять на CPU-bound нагрузку, которую здесь неоднократно упомянули?
«select a = b» сравнивает бинарные представления. А текстовые представления в PostgreSQL одинаковые. А в MySQL бинарные числа разные, и текстовые представления разные. Так понятно?
> чтобы понять, что значения «одинаковые» их надо сравнить. «одинаковость» — это не текстовое представление глазами сверять. ох, как с вами тяжело.

Весь пример демонстрировал, что PostgreSQL показывает одинаковые текстовые представления для разных бинарных чисел, а MySQL так никогда не делает. Ничего больше, ничего меньше. Все остальные следствия из этого простого факта вы выдумали сами и спорите сейчас с воображаемым собеседником.
Я там ниже написал про read-free replication. Надо сказать, я удачно зашёл на Хабр. Интересно, есть вообще темы в MySQL, которые в этом посте про PostgreSQL ещё не обсудили? :)
> а как мне понять, какой флоат более результат, чем другой)

вас вот что смутило в моём примере. PostgreSQL показывает два _разных_ бинарных флоата как одинаковые числа. Поэтому сравнение выдаёт 'false', что неинтуитивно. MySQL разные _бинарные_ числа всегда показывает разными. Поэтому и результат сравнения вопросов не вызывает.

> и как там всё таки про рассылки, где правильная, можно всё таки пояснить? гугл мне как минимум дает майсиквеловские и мариишные листы

Ну кому вы больше доверяете, туда и пишите. Возвращаясь к примеру с дистрибутивами Linux, вот есть у вас проблема с Linux kernel. Можно написать в LKML. А можно в список рассылки своего дистрибутива. А можно в местную группу пользователей. Или везде сразу.
Всем, кто обсуждает проблемы row-based репликации в MySQL (именно так её правильно называть, чтобы говорить на одном с PostgreSQL и избежать путаницы с терминами логическая/бинарная/физическая репликация). Основная проблема, как я вижу, это чтение при репликации (так правильнее называть проблему с CPU-bound, как её здесь часто называют). Решение есть, например в TokuDB, называется read-free replication. Читать можно начинать отсюда: https://github.com/percona/tokudb-engine/wiki/Read-Free-Replication-with-TokuDB
Так может это потому, что MySQL 5.7 ещё как бы не вышел? GA версия появится скорее всего через пару недель на Oracle OpenWorld. Как обычно какого-то широкого использвания не стоит ждать в течение года. А вот по-настоящему серьёзных исследований нужно ждать, когда на 5.7 начнут переходить тяжеловесы типа Facebook/Twitter/LinkedIn/Dropbox.
Всегда пожалуйста. Прошу не рассматривать это как личный наезд, а как замечание к дальнейшему его улучшению. Текущую версию я слышал два раза и к сожалению это всё существенное, что я смог из неё вынести.
> далее, что мне там обсуждать: как ФЛОАТЫ на РАВЕНСТВО = сравнивать или что бинарная репликация sql тредом обрабатывается?

флоаты на равенство сравнивать можно. результаты вычислений нельзя. это вы слышали звон, но не очень в курсе где он.

Вы хоть книжки почитайте по теме. Вот эта хорошая: «What Every Computer Scientist Should Know About Floating-Point Arithmetic, by David Goldberg».
Да напишите хоть в какой-нибудь уже.

А так да, есть несколько компаний, которые поддерживают списки рассылки и форумы. Причём, в список рассылки Percona или MariaDB можно задавать вопросы не только по продуктам Перконы, но и по Oracle и MariaDB. И в этих списках отвечают на вопросы абсолютно бесплатно. Я лично отвечал.

А ещё есть локальные группы пользователей. Например, московская. Со своим списком рассылки, где не очень большой трафик, но на вопросы отвечают довольно оперативно. Я лично отвечал тоже, да. Безвомездно, то есть даром.

А теперь главный вопрос: в каком из списков рассылки можно почитать описание проблемы Олега? Ах, ну да, он же никуда и не писал. Но чему тогда удивляться?
> Разница в том что если мы хотим видеть только достоверные десятичные цифры, то выводить надо DBL_DIG=15 цифр.

Неверно. Для некоторых чисел можно, а иногда нужно выводить больше DBL_DIG цифр. См. исходный пример. А для некоторых чисел этого делать нельзя.

> Если мы хотим однозначное соответствие между бинарным и десятичным представлениями, то выводить надо DBL_DIG+2=17 цифр.

Не существует никакого однозначного соответствия для DBL_DIG+2=17 цифр. А PostgreSQL вообще использует DBL_DIG+3=18. Оно впрочем и для DBL_DIG не существует, это не о том.

> Никакого undefined behavior, все по стандарту, просто значение по умолчанию реализует одно поведение, если надо другое ставим extra_float_digits=2 и все.

Нет, не всё. Почитайте определение FLT_DIG/DBL_DIG. И ещё почему PostgreSQL сначала использовал extra_float_digits=2, а потом вдруг стал extra_float_digits=3 при экспорте. Тут ссылка уже была.
> Мусор никому не мешает, до тех пор пока «Conversion to an external character sequence must be such that conversion back using round to even will recover the original number.»

О том о речь. «До тех пор, пока», то есть undefined behavior, на которое PostgreSQL расчитывает при экпорте/импорте. И где-то как-то оно работает, пока не случится ой.
Ну расскажем, чего уж там.

> Тестировали или умозрительно злорадствуете? Все импортируется.

Да, мы с Михаилом уже выяснили, что pg_dump подставляет костыль. Но всё сложнее, см. ниже.

> А здесь тоже тупой постгрес виноват:

Нет, здесь виноват злой стандарт IEEE 754, который не имеет точного бинарного представления для десятичных чисел 2.1 или 0.1. Соответственно, мы видим округлённую бесконечную двоичную дробь. Причём в силу потери точности результат для ::real выглядит хуже, чем для ::float8. Но это речь не об этой проблеме.

Проблема заключается в том, что стандарт IEEE 754 (точнее, выбранный формат данных) определяет максимальное число значимых цифр для каждого типа данных, для которых гарантируется преобразование без потерь из десятичного (строкового) представления во внутреннее (бинарное) и обратно. Для double precision aka float8 это 15 значимых десятичных цифр (константа DBL_DIG). Для чисел с бОльшим количеством значимых цифр преобразование туда-обратно может быть без потерь, а может быть и с потерями — это зависит от числа и деталей реализации, стандарт ничего не гарантирует.

Вот когда PostgreSQL работает DBL_DIG (т.е. с extra_float_digits=0), то он может печатать невалидные данные в разных граничных случаях, или просто работать неинтуитивно с точки зрения приложений, как я показал на примерах.

А когда он начинает печатать все числа с DBL_DIG + extra_float_digits, он нарушает стандарт. Это может выражаться как в относительно безобидных вещах, типа:

test=# select 0.3::float8;
        float8
----------------------
 0.299999999999999989


(технически ответ верный, но мог бы показать более короткое эквивалентное представление: 0.3)

или

test=# select .1::float8;
        float8
----------------------
 0.100000000000000006
(1 row)


(здесь ответ верный до DBL_DIG значимых цифр, но потом идёт «мусор» в виде 006)

Кстати, вот этот «мусор» за пределами 15 значимых цифр имеет неопределённое содержимое, т.е. зависит от реализации, ОС, версии libc, процессора и флагов компиляции.

Этот мусор может иметь и более опасные последствия. Поскольку стандарт не гарантирует преобразование без потерь при печати чисел с числом десятичных цифр > DBL_DIG, данные могут искажаться при экспорте/импорте. Например, сделали дамп гео данных на Linux/Intel, а импортировали на Solaris/Sparc. Данные «чуть-чуть» уплылили. А потом ещё «чуть-чуть». А потом самолёты начинают падать ;)

> Ну расскажите нам, как и что вы исправили

MySQL для чисел с плавающей точкой работает так:

1. Выбирает наиболее короткое представление («0.3» напечатается как «0.3», а не как «0.299999999999999989»)
2. Избегает «мусора», т.е. любая напечатанная цифра является значимой и не зависит от ОС/libc/процессора и т.д. («0.1» напечатается как «0.1»
3. Автоматически выбирается «безопасное» для преобразования без потерь количество десятичных цифр. Нет никаких костылей типа extra_float_digits. Если число напечатано, значит MySQL сможет его считать обратно при любой конфигурации, ОС, libc, процессора и флагов компиляции.

Ну как-то так.
Николай, говорят можно в песочнице создать пост. Спасибо, что пытались помочь! :)
Ну, то есть pg_dump вовремя подставляет костыль. Что конечно замечательно, но:

1. невалидные данные с extra_float_digits остаются невалидными данными
2. костыль остаётся костылём (подробнее ниже, там ещё один товарищ жаждет объяснений)
3. одними дампами проблема не ограничивается. Ну, например, с дефолтным extra_float_digits:

est=# create table d2(a float8, b float8);
CREATE TABLE
test=# insert into d2 values (2, 2.0000000000000004);
INSERT 0 1
test=# select * from d2;
 a | b
---+---
 2 | 2
(1 row)
test=# select a = b from d2;
 ?column?
----------
 f
(1 row)


Может для PostgreSQL это нормально, но MySQL себе такого не позволяет.

> вот пример комунити — написал, разобрали

Мне вот интересно, вы действительно считаете, что в MySQL community нет списков рассылок, форумов и прочего, где пользователям отвечают на вопросы?
Увы и ах, печатать больше чем DBL_DIG (15) цифр нельзя. Почитайте определение DBL_DIG. То есть, extra_float_digits — это костыль, чтобы исправить один случай и сломать другие.

Information

Rating
Does not participate
Date of birth
Registered
Activity