https://issues.apache.org/jira/browse/KUDU-2625 is the JIRA to track this
issue.  Feel free to add details, comments, etc.


Thanks,

Alexey

On Sat, Nov 17, 2018 at 7:13 AM Alexey Serbin <aser...@cloudera.com> wrote:

> Hey Todd,
>
> Yes, that behavior is a bit strange especially given the fact that the
> behavior differs when it comes to duplicate rows and other errors that
> happen at later stages of 'applying' write operations at the server side.
>
> I'll open a JIRA item about this issue.  If anyone disagrees, we can
> resolve the JIRA item as needed.
>
>
> Thanks,
>
> Alexey
>
> On Sat, Nov 17, 2018 at 12:01 AM Todd Lipcon <t...@cloudera.com> wrote:
>
>> Hey Alexey,
>>
>> I think your explanation makes sense from an implementation perspective.
>> But, I think we should treat this behavior as a bug. From the user
>> perspective, such an error is a per-row data issue and should only affect
>> the row with the problem, not some arbitrary subset of rows in the batch
>> which happened to share a partition.
>>
>> Does anyone disagree?
>>
>> Todd
>>
>> On Fri, Nov 16, 2018, 9:28 PM Alexey Serbin <aser...@cloudera.com wrote:
>>
>>> Hi Boris,
>>>
>>> Kudu clients (both Java and C++ ones) send write operations to
>>> corresponding tablet servers in batches when using the AUTO_FLUSH_BACKGROUND
>>> and MANUAL_FLUSH modes.  When a tablet server receives a Write RPC
>>> (WriteRequestPB is the corresponding type of the parameter), it decodes the
>>> operations from the batch:
>>> https://github.com/apache/kudu/blob/master/src/kudu/tablet/local_tablet_writer.h#L97
>>>
>>> While decoding operations from a batch, various constraints are being
>>> checked.  One of those is checking for nulls in non-nullable columns.  If
>>> there is a row in the batch that violates the non-nullable constraint, the
>>> whole batch is rejected.
>>>
>>> That's exactly what happened in your example: a batch to one tablet
>>> consisted of 3 rows one of which had a row with violation of the
>>> non-nullable constraint for the dt_tm column, so the whole batch of 3
>>> operations was rejected.  You can play with different partition schemes:
>>> e.g., in case of 10 hashed partitions it might happen that only 2
>>> operations would be rejected, in case of 30 partitions -- just the single
>>> key==2 row could be rejected.
>>>
>>> BTW, that might also happen if using the MANUAL_FLUSH mode.  However,
>>> with the AUTO_FLUSH_SYNC mode, the client sends operations in batches of
>>> size 1.
>>>
>>>
>>> Kind regards,
>>>
>>> Alexey
>>>
>>> On Fri, Nov 16, 2018 at 7:24 PM Boris Tyukin <bo...@boristyukin.com>
>>> wrote:
>>>
>>>> Hi Todd,
>>>>
>>>> We are on Kudu 1.5 still and I used Kudu client 1.7
>>>>
>>>> Thanks,
>>>> Boris
>>>>
>>>> On Fri, Nov 16, 2018, 17:07 Todd Lipcon <t...@cloudera.com wrote:
>>>>
>>>>> Hi Boris,
>>>>>
>>>>> This is interesting. Just so we're looking at the same code, what
>>>>> version of the kudu-client dependency have you specified, and what version
>>>>> of the server?
>>>>>
>>>>> -Todd
>>>>>
>>>>> On Fri, Nov 16, 2018 at 1:12 PM Boris Tyukin <bo...@boristyukin.com>
>>>>> wrote:
>>>>>
>>>>>> Hey guys,
>>>>>>
>>>>>> I am playing with Kudu Java client (wow it is fast), using mostly
>>>>>> code from Kudu Java example.
>>>>>>
>>>>>> While learning about exceptions during rows inserts, I stumbled upon
>>>>>> something I could not explain.
>>>>>>
>>>>>> If I insert 10 rows into a brand new Kudu table
>>>>>> (AUTO_FLUSH_BACKGROUND mode) and I make one row to be "bad" intentionally
>>>>>> (one column cannot be NULL), I actually get 3 rows that cannot be 
>>>>>> inserted
>>>>>> into Kudu, not 1 as I was expected.
>>>>>>
>>>>>> But if I do session.flush() after every single insert, I get only one
>>>>>> error row (but this ruins the purpose of AUTO_FLUSH_BACKGROUND mode).
>>>>>>
>>>>>> Any ideas one? We cannot afford losing data and need to track all
>>>>>> rows which cannot be inserted.
>>>>>>
>>>>>> AUTO_FLUSH mode works much better and I do not have an issue like
>>>>>> above, but then it is way slower than AUTO_FLUSH_BACKGROUND.
>>>>>>
>>>>>> My code is below. It is in Groovy, but I think you will get an idea :)
>>>>>> https://gist.github.com/boristyukin/8703d2c6ec55d6787843aa133920bf01
>>>>>>
>>>>>> Here is output from my test code that hopefully illustrates my
>>>>>> confusion - out of 10 rows inserted, 9 should be good and 1 bad, but it
>>>>>> turns out Kudu flagged 3 as bad:
>>>>>>
>>>>>> Created table kudu_groovy_example
>>>>>> Inserting 10 rows in AUTO_FLUSH_BACKGROUND flush mode ...
>>>>>> (int32 key=1, string value="value 1", unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.469000Z)
>>>>>> (int32 key=2, string value=NULL)  BAD ROW
>>>>>> (int32 key=3, string value="value 3", unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.595000Z)
>>>>>> (int32 key=4, string value=NULL, unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.596000Z)
>>>>>> (int32 key=5, string value="value 5", unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.597000Z)
>>>>>> (int32 key=6, string value=NULL, unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.597000Z)
>>>>>> (int32 key=7, string value="value 7", unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.598000Z)
>>>>>> (int32 key=8, string value=NULL, unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.602000Z)
>>>>>> (int32 key=9, string value="value 9", unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.603000Z)
>>>>>> (int32 key=10, string value=NULL, unixtime_micros
>>>>>> dt_tm=2018-11-16T20:57:03.603000Z)
>>>>>> 3 errors inserting rows - why 3???? only 1 expected to be bad...
>>>>>> there were errors inserting rows to Kudu
>>>>>> the first few errors follow:
>>>>>> ??? key 1 and 6 supposed to be fine!
>>>>>> Row error for primary key=[-128, 0, 0, 1], tablet=null, server=null,
>>>>>> status=Invalid argument: No value provided for required column:
>>>>>> dt_tm[unixtime_micros NOT NULL] (error 0)
>>>>>> Row error for primary key=[-128, 0, 0, 2], tablet=null, server=null,
>>>>>> status=Invalid argument: No value provided for required column:
>>>>>> dt_tm[unixtime_micros NOT NULL] (error 0)
>>>>>> Row error for primary key=[-128, 0, 0, 6], tablet=null, server=null,
>>>>>> status=Invalid argument: No value provided for required column:
>>>>>> dt_tm[unixtime_micros NOT NULL] (error 0)
>>>>>> Rows counted in 485 ms
>>>>>> Table has 7 rows - ??? supposed to be 9!
>>>>>> INT32 key=4, STRING value=NULL, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.596000Z
>>>>>> INT32 key=8, STRING value=NULL, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.602000Z
>>>>>> INT32 key=9, STRING value=value 9, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.603000Z
>>>>>> INT32 key=3, STRING value=value 3, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.595000Z
>>>>>> INT32 key=10, STRING value=NULL, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.603000Z
>>>>>> INT32 key=5, STRING value=value 5, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.597000Z
>>>>>> INT32 key=7, STRING value=value 7, UNIXTIME_MICROS
>>>>>> dt_tm=2018-11-16T20:57:03.598000Z
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Todd Lipcon
>>>>> Software Engineer, Cloudera
>>>>>
>>>>

Reply via email to