Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hG5Tf-0006zK-Cs for pgsql-hackers@arkaria.postgresql.org; Mon, 15 Apr 2019 17:33:07 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hG5Tc-0002Nl-Uz for pgsql-hackers@arkaria.postgresql.org; Mon, 15 Apr 2019 17:33:04 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hG5Tc-0002M9-JC for pgsql-hackers@lists.postgresql.org; Mon, 15 Apr 2019 17:33:04 +0000 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hG5TZ-0001bh-0k for pgsql-hackers@postgresql.org; Mon, 15 Apr 2019 17:33:03 +0000 Received: by mail-wr1-x442.google.com with SMTP id k11so23058906wro.5 for ; Mon, 15 Apr 2019 10:33:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=DaYvRBd2yTvJYZkVD9G11DeuLDMN2a6Bz7k5DgK1Bfc=; b=Q9uC+LKQIMY53rjKIKMTlgejZtRViTNbvA7BsZCsOeMzEGJ4Ye205loY7OwvOR4+Ih LVmHvZsxyu0UWI5AkVR5zNfNz6c+6DvSloZ3MEvok16WoPFKSZIw1wpEaBm3KAGB/WsN GAyb58f2Glv0Ycnle7/Wn2GqE5VRFnDN6rCv2wQB6eAt0dPRQNgbLKhOu2ZO+3XWZp39 ie2rg+r+VVfzUyuqY2dEoOGJGzV17xiQGolHIc6/m0BgJ8/xQcIctdUnivQhaxCPXSea JxAdiZMOgcW7pNW5kZ0i55OhRUayr41sfHo3OfoDn3sKo4IY3J0wwXrz4/xjelotr67Z VokA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=DaYvRBd2yTvJYZkVD9G11DeuLDMN2a6Bz7k5DgK1Bfc=; b=bktB+qJEUrS2B+Td5kvx/8mEEmNOg+9jemRF5MTuHFSKstmmJMtCuVynlEgUXZXWmh pvZo/ciAvkcWzjiDVr/r6enUeDfZg/yqk3YPb+UyN00TmJEeNCe/E7tCnqz7f1N+Yb2E V4lZ0fpqqbtRCC64KsFt1Bi8jrZ58JacSjKl05BS4QLgF0v+99Nd0+vANf1Q3mV49X0j Lh5WjegIZu9tjA497IYY4JFNeDEnflVtqd2P3iyN3xlZq1u/lqGteDF08hSU94Xv/gdW Vab0Af+d2kaAgYvfGtI6uG2w0tPoe2PQ1nr108Dc1W5sAJAPdv3r45KB0hlkoJlukBZn dztA== X-Gm-Message-State: APjAAAXoOQk60CgamsbMpWw1YrcnpbMMZfEFWKvhZiItkWxIQ/HOSZhQ Fgqm3ODlW5pub9FFfjjOW+xJzg== X-Google-Smtp-Source: APXvYqxVZcflQIc//LS1KqQT7bwMo4/T8YUH9y3fB8DFIwvIxDayN4zNW4dEhHdjRH4kzkIRk1lElg== X-Received: by 2002:adf:8bc5:: with SMTP id w5mr45265136wra.226.1555349579325; Mon, 15 Apr 2019 10:32:59 -0700 (PDT) Received: from localhost (ip-86-49-243-43.net.upcbroadband.cz. [86.49.243.43]) by smtp.gmail.com with ESMTPSA id u189sm20064841wme.25.2019.04.15.10.32.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 15 Apr 2019 10:32:55 -0700 (PDT) Date: Mon, 15 Apr 2019 19:32:54 +0200 From: Tomas Vondra To: Ashwin Agrawal Cc: Heikki Linnakangas , Tom Lane , Mark Kirkwood , PostgreSQL mailing lists Subject: Re: Zedstore - compressed in-core columnar storage Message-ID: <20190415173254.nlnk2xqhgt7c5pta@development> References: <6A2B85A8-1ABD-4F85-981E-C94172D662FD@pivotal.io> <11257.1554994460@sss.pgh.pa.us> <20190414163947.owdw4gyjui36rakf@development> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: NeoMutt/20180716-1444-295967 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Mon, Apr 15, 2019 at 09:29:37AM -0700, Ashwin Agrawal wrote: > On Sun, Apr 14, 2019 at 9:40 AM Tomas Vondra > wrote: > > On Thu, Apr 11, 2019 at 06:20:47PM +0300, Heikki Linnakangas wrote: > >On 11/04/2019 17:54, Tom Lane wrote: > >>Ashwin Agrawal writes: > >>>Thank you for trying it out. Yes, noticed for certain patterns > pg_lzcompress() actually requires much larger output buffers. Like for > one 86 len source it required 2296 len output buffer. Current zedstore > code doesn’t handle this case and errors out. LZ4 for same patterns > works fine, would highly recommend using LZ4 only, as anyways speed is > very fast as well with it. > >> > >>You realize of course that *every* compression method has some inputs > that > >>it makes bigger.  If your code assumes that compression always > produces a > >>smaller string, that's a bug in your code, not the compression > algorithm. > > > >Of course. The code is not making that assumption, although clearly > >there is a bug there somewhere because it throws that error. It's > >early days.. > > > >In practice it's easy to weasel out of that, by storing the data > >uncompressed, if compression would make it longer. Then you need an > >extra flag somewhere to indicate whether it's compressed or not. It > >doesn't break the theoretical limit because the actual stored length > >is then original length + 1 bit, but it's usually not hard to find a > >place for one extra bit. > > > > Don't we already have that flag, though? I see ZSCompressedBtreeItem has > t_flags, and there's ZSBT_COMPRESSED, but maybe it's more complicated. > > The flag ZSBT_COMPRESSED differentiates between container (compressed) > item and plain (uncompressed item). Current code is writtten such that > within container (compressed) item, all the data is compressed. If need > exists to store some part of uncompressed data inside container item, then > this additional flag would be required to indicate the same. Hence its > different than ZSBT_COMPRESSED. I am thinking one of the ways could be to > just not store this datum in container item if can't be compressed and > just store it as plain item with uncompressed data, this additional flag > won't be required. Will know more once write code for this. I see. Perhaps it'd be better to call the flag ZSBT_CONTAINER, when it means "this is a container". And then have another flag to track whether the container is compressed or not. But as I suggested elsewhere in this thread, I think it might be better to store some ID of the compression algorithm used instead of a simple flag. FWIW when I had to deal with incremental compression (adding data into already compressed buffers), which is what seems to be happening here, I found it very useful/efficient to allow partially compressed buffers and only trigger recompressin when absolutely needed. Applied to this case, the container would first store compressed chunk, followed by raw (uncompressed) data. Say, like this: ZSContainerData { // header etc. int nbytes; /* total bytes in data */ int ncompressed; /* ncompressed <= nbytes, fully compressed when * (ncompressed == nbytes) */ char data[FLEXIBLE_ARRAY_MEMBER]; } When adding a value to the buffer, it'd be simply appended to the data array. When the container would grow too much (can't fit on the page or something), recompression is triggered. cheers -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services